
bin/kernel:     file format elf32-i386


Disassembly of section .text:

c0100000 <kern_entry>:

.text
.globl kern_entry
kern_entry:
    # load pa of boot pgdir
    movl $REALLOC(__boot_pgdir), %eax
c0100000:	b8 00 40 12 00       	mov    $0x124000,%eax
    movl %eax, %cr3
c0100005:	0f 22 d8             	mov    %eax,%cr3

    # enable paging
    movl %cr0, %eax
c0100008:	0f 20 c0             	mov    %cr0,%eax
    orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP), %eax
c010000b:	0d 2f 00 05 80       	or     $0x8005002f,%eax
    andl $~(CR0_TS | CR0_EM), %eax
c0100010:	83 e0 f3             	and    $0xfffffff3,%eax
    movl %eax, %cr0
c0100013:	0f 22 c0             	mov    %eax,%cr0

    # update eip
    # now, eip = 0x1.....
    leal next, %eax
c0100016:	8d 05 1e 00 10 c0    	lea    0xc010001e,%eax
    # set eip = KERNBASE + 0x1.....
    jmp *%eax
c010001c:	ff e0                	jmp    *%eax

c010001e <next>:
next:

    # unmap va 0 ~ 4M, it's temporary mapping
    xorl %eax, %eax
c010001e:	31 c0                	xor    %eax,%eax
    movl %eax, __boot_pgdir
c0100020:	a3 00 40 12 c0       	mov    %eax,0xc0124000

    # set ebp, esp
    movl $0x0, %ebp
c0100025:	bd 00 00 00 00       	mov    $0x0,%ebp
    # the kernel stack region is from bootstack -- bootstacktop,
    # the kernel stack size is KSTACKSIZE (8KB)defined in memlayout.h
    movl $bootstacktop, %esp
c010002a:	bc 00 30 12 c0       	mov    $0xc0123000,%esp
    # now kernel stack is ready , call the first C function
    call kern_init
c010002f:	e8 02 00 00 00       	call   c0100036 <kern_init>

c0100034 <spin>:

# should never get here
spin:
    jmp spin
c0100034:	eb fe                	jmp    c0100034 <spin>

c0100036 <kern_init>:
int kern_init(void) __attribute__((noreturn));
void grade_backtrace(void);
static void lab1_switch_test(void);

int
kern_init(void) {
c0100036:	f3 0f 1e fb          	endbr32 
c010003a:	55                   	push   %ebp
c010003b:	89 e5                	mov    %esp,%ebp
c010003d:	83 ec 28             	sub    $0x28,%esp
    extern char edata[], end[]; //声明外部变量 edata 和 end
    memset(edata, 0, end - edata); // 将数据段清零
c0100040:	b8 70 71 12 c0       	mov    $0xc0127170,%eax
c0100045:	2d 00 60 12 c0       	sub    $0xc0126000,%eax
c010004a:	89 44 24 08          	mov    %eax,0x8(%esp)
c010004e:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0100055:	00 
c0100056:	c7 04 24 00 60 12 c0 	movl   $0xc0126000,(%esp)
c010005d:	e8 8b 86 00 00       	call   c01086ed <memset>

    cons_init();                // init the console 初始化控制台
c0100062:	e8 1c 1e 00 00       	call   c0101e83 <cons_init>

    const char *message = "(THU.CST) os is loading ...";
c0100067:	c7 45 f4 00 90 10 c0 	movl   $0xc0109000,-0xc(%ebp)
    cprintf("%s\n\n", message);// 将消息输出到控制台
c010006e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100071:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100075:	c7 04 24 1c 90 10 c0 	movl   $0xc010901c,(%esp)
c010007c:	e8 58 02 00 00       	call   c01002d9 <cprintf>

    print_kerninfo();// 输出内核信息的函数
c0100081:	e8 16 09 00 00       	call   c010099c <print_kerninfo>

    grade_backtrace(); //调用回溯函数，通常用于调试，显示函数调用栈。
c0100086:	e8 a9 00 00 00       	call   c0100134 <grade_backtrace>

    pmm_init();                 // init physical memory management初始化物理内存管理
c010008b:	e8 f0 3c 00 00       	call   c0103d80 <pmm_init>

    pic_init();                 // init interrupt controller初始化可编程中断控制器
c0100090:	e8 69 1f 00 00       	call   c0101ffe <pic_init>
    idt_init();                 // init interrupt descriptor table初始化中断描述符表
c0100095:	e8 e9 20 00 00       	call   c0102183 <idt_init>

    vmm_init();                 // init virtual memory management 初始化虚拟内存管理
c010009a:	e8 99 59 00 00       	call   c0105a38 <vmm_init>

    ide_init();                 // init ide devices初始化IDE设备
c010009f:	e8 14 0d 00 00       	call   c0100db8 <ide_init>
    swap_init();                // init swap 初始化交换分区
c01000a4:	e8 a2 63 00 00       	call   c010644b <swap_init>

    clock_init();               // init clock interrupt 初始化时钟中断
c01000a9:	e8 1c 15 00 00       	call   c01015ca <clock_init>
    intr_enable();              // enable irq interrupt启用中断
c01000ae:	e8 97 20 00 00       	call   c010214a <intr_enable>

    //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test()
    // user/kernel mode switch test
    lab1_switch_test();
c01000b3:	e8 87 01 00 00       	call   c010023f <lab1_switch_test>

    /* do nothing */
    while (1);
c01000b8:	eb fe                	jmp    c01000b8 <kern_init+0x82>

c01000ba <grade_backtrace2>:
}

//不进行内联的回溯函数，调用 mon_backtrace 显示当前的调用栈。
void __attribute__((noinline))
grade_backtrace2(int arg0, int arg1, int arg2, int arg3) {
c01000ba:	f3 0f 1e fb          	endbr32 
c01000be:	55                   	push   %ebp
c01000bf:	89 e5                	mov    %esp,%ebp
c01000c1:	83 ec 18             	sub    $0x18,%esp
    mon_backtrace(0, NULL, NULL);
c01000c4:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01000cb:	00 
c01000cc:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01000d3:	00 
c01000d4:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c01000db:	e8 65 0c 00 00       	call   c0100d45 <mon_backtrace>
}
c01000e0:	90                   	nop
c01000e1:	c9                   	leave  
c01000e2:	c3                   	ret    

c01000e3 <grade_backtrace1>:
//不进行内联的回溯函数，传递参数到 grade_backtrace2
void __attribute__((noinline))
grade_backtrace1(int arg0, int arg1) {
c01000e3:	f3 0f 1e fb          	endbr32 
c01000e7:	55                   	push   %ebp
c01000e8:	89 e5                	mov    %esp,%ebp
c01000ea:	53                   	push   %ebx
c01000eb:	83 ec 14             	sub    $0x14,%esp
    grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1);
c01000ee:	8d 4d 0c             	lea    0xc(%ebp),%ecx
c01000f1:	8b 55 0c             	mov    0xc(%ebp),%edx
c01000f4:	8d 5d 08             	lea    0x8(%ebp),%ebx
c01000f7:	8b 45 08             	mov    0x8(%ebp),%eax
c01000fa:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c01000fe:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100102:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c0100106:	89 04 24             	mov    %eax,(%esp)
c0100109:	e8 ac ff ff ff       	call   c01000ba <grade_backtrace2>
}
c010010e:	90                   	nop
c010010f:	83 c4 14             	add    $0x14,%esp
c0100112:	5b                   	pop    %ebx
c0100113:	5d                   	pop    %ebp
c0100114:	c3                   	ret    

c0100115 <grade_backtrace0>:
//不进行内联的回溯函数，传递参数到 grade_backtrace1
void __attribute__((noinline))
grade_backtrace0(int arg0, int arg1, int arg2) {
c0100115:	f3 0f 1e fb          	endbr32 
c0100119:	55                   	push   %ebp
c010011a:	89 e5                	mov    %esp,%ebp
c010011c:	83 ec 18             	sub    $0x18,%esp
    grade_backtrace1(arg0, arg2);
c010011f:	8b 45 10             	mov    0x10(%ebp),%eax
c0100122:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100126:	8b 45 08             	mov    0x8(%ebp),%eax
c0100129:	89 04 24             	mov    %eax,(%esp)
c010012c:	e8 b2 ff ff ff       	call   c01000e3 <grade_backtrace1>
}
c0100131:	90                   	nop
c0100132:	c9                   	leave  
c0100133:	c3                   	ret    

c0100134 <grade_backtrace>:
//触发回溯的起始点，传递初始化函数地址。
void
grade_backtrace(void) {
c0100134:	f3 0f 1e fb          	endbr32 
c0100138:	55                   	push   %ebp
c0100139:	89 e5                	mov    %esp,%ebp
c010013b:	83 ec 18             	sub    $0x18,%esp
    grade_backtrace0(0, (int)kern_init, 0xffff0000);
c010013e:	b8 36 00 10 c0       	mov    $0xc0100036,%eax
c0100143:	c7 44 24 08 00 00 ff 	movl   $0xffff0000,0x8(%esp)
c010014a:	ff 
c010014b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010014f:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0100156:	e8 ba ff ff ff       	call   c0100115 <grade_backtrace0>
}
c010015b:	90                   	nop
c010015c:	c9                   	leave  
c010015d:	c3                   	ret    

c010015e <lab1_print_cur_status>:
//打印当前的段寄存器状态。
static void
lab1_print_cur_status(void) {
c010015e:	f3 0f 1e fb          	endbr32 
c0100162:	55                   	push   %ebp
c0100163:	89 e5                	mov    %esp,%ebp
c0100165:	83 ec 28             	sub    $0x28,%esp
    static int round = 0;
    uint16_t reg1, reg2, reg3, reg4;
    //嵌入汇编代码，确保编译器不优化这些代码。
    asm volatile (
c0100168:	8c 4d f6             	mov    %cs,-0xa(%ebp)
c010016b:	8c 5d f4             	mov    %ds,-0xc(%ebp)
c010016e:	8c 45 f2             	mov    %es,-0xe(%ebp)
c0100171:	8c 55 f0             	mov    %ss,-0x10(%ebp)
            "mov %%cs, %0;"// 将当前代码段寄存器的值移动到 reg1
            "mov %%ds, %1;"
            "mov %%es, %2;"
            "mov %%ss, %3;"
            : "=m"(reg1), "=m"(reg2), "=m"(reg3), "=m"(reg4));
    cprintf("%d: @ring %d\n", round, reg1 & 3);//打印当前的 round、权限级（ring）和各段寄存器的值。
c0100174:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0100178:	83 e0 03             	and    $0x3,%eax
c010017b:	89 c2                	mov    %eax,%edx
c010017d:	a1 00 60 12 c0       	mov    0xc0126000,%eax
c0100182:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100186:	89 44 24 04          	mov    %eax,0x4(%esp)
c010018a:	c7 04 24 21 90 10 c0 	movl   $0xc0109021,(%esp)
c0100191:	e8 43 01 00 00       	call   c01002d9 <cprintf>
    cprintf("%d:  cs = %x\n", round, reg1);
c0100196:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010019a:	89 c2                	mov    %eax,%edx
c010019c:	a1 00 60 12 c0       	mov    0xc0126000,%eax
c01001a1:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001a5:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001a9:	c7 04 24 2f 90 10 c0 	movl   $0xc010902f,(%esp)
c01001b0:	e8 24 01 00 00       	call   c01002d9 <cprintf>
    cprintf("%d:  ds = %x\n", round, reg2);
c01001b5:	0f b7 45 f4          	movzwl -0xc(%ebp),%eax
c01001b9:	89 c2                	mov    %eax,%edx
c01001bb:	a1 00 60 12 c0       	mov    0xc0126000,%eax
c01001c0:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001c4:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001c8:	c7 04 24 3d 90 10 c0 	movl   $0xc010903d,(%esp)
c01001cf:	e8 05 01 00 00       	call   c01002d9 <cprintf>
    cprintf("%d:  es = %x\n", round, reg3);
c01001d4:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c01001d8:	89 c2                	mov    %eax,%edx
c01001da:	a1 00 60 12 c0       	mov    0xc0126000,%eax
c01001df:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001e3:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001e7:	c7 04 24 4b 90 10 c0 	movl   $0xc010904b,(%esp)
c01001ee:	e8 e6 00 00 00       	call   c01002d9 <cprintf>
    cprintf("%d:  ss = %x\n", round, reg4);
c01001f3:	0f b7 45 f0          	movzwl -0x10(%ebp),%eax
c01001f7:	89 c2                	mov    %eax,%edx
c01001f9:	a1 00 60 12 c0       	mov    0xc0126000,%eax
c01001fe:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100202:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100206:	c7 04 24 59 90 10 c0 	movl   $0xc0109059,(%esp)
c010020d:	e8 c7 00 00 00       	call   c01002d9 <cprintf>
    round ++;//将 round 增加1，以便每次调用时记录状态。
c0100212:	a1 00 60 12 c0       	mov    0xc0126000,%eax
c0100217:	40                   	inc    %eax
c0100218:	a3 00 60 12 c0       	mov    %eax,0xc0126000
}
c010021d:	90                   	nop
c010021e:	c9                   	leave  
c010021f:	c3                   	ret    

c0100220 <lab1_switch_to_user>:

static void
lab1_switch_to_user(void) {
c0100220:	f3 0f 1e fb          	endbr32 
c0100224:	55                   	push   %ebp
c0100225:	89 e5                	mov    %esp,%ebp
    // 从内核模式切换到用户模式
    //LAB1 CHALLENGE 1 : TODO
    asm volatile (
c0100227:	83 ec 08             	sub    $0x8,%esp
c010022a:	cd 78                	int    $0x78
c010022c:	89 ec                	mov    %ebp,%esp
	    "int %0 \n"//通过触发一个中断，将控制权转移到内核，切换到用户模式。
	    "movl %%ebp, %%esp"// 将基指针（EBP）值移动到堆栈指针（ESP），恢复堆栈指针。
	    : 
	    : "i"(T_SWITCH_TOU)//T_SWITCH_TOU是一个常量，表示切换到用户态的中断号。传入常量 T_SWITCH_TOU
	);
}
c010022e:	90                   	nop
c010022f:	5d                   	pop    %ebp
c0100230:	c3                   	ret    

c0100231 <lab1_switch_to_kernel>:

static void
lab1_switch_to_kernel(void) {
c0100231:	f3 0f 1e fb          	endbr32 
c0100235:	55                   	push   %ebp
c0100236:	89 e5                	mov    %esp,%ebp
    // 从用户模式切换到内核模式
    //LAB1 CHALLENGE 1 :  TODO
    asm volatile (
c0100238:	cd 79                	int    $0x79
c010023a:	89 ec                	mov    %ebp,%esp
	    "int %0 \n"// 同样触发中断，这里用的是 T_SWITCH_TOK，从用户态切换回内核态。
	    "movl %%ebp, %%esp \n"//恢复堆栈指针
	    : 
	    : "i"(T_SWITCH_TOK)//传入常量 T_SWITCH_TOU
	);
}
c010023c:	90                   	nop
c010023d:	5d                   	pop    %ebp
c010023e:	c3                   	ret    

c010023f <lab1_switch_test>:

//测试用户模式和内核模式切换。
//调用 lab1_print_cur_status 打印当前状态，进行模式切换，然后再次打印状态。
static void
lab1_switch_test(void) {
c010023f:	f3 0f 1e fb          	endbr32 
c0100243:	55                   	push   %ebp
c0100244:	89 e5                	mov    %esp,%ebp
c0100246:	83 ec 18             	sub    $0x18,%esp
    lab1_print_cur_status();
c0100249:	e8 10 ff ff ff       	call   c010015e <lab1_print_cur_status>
    cprintf("+++ switch to  user  mode +++\n");
c010024e:	c7 04 24 68 90 10 c0 	movl   $0xc0109068,(%esp)
c0100255:	e8 7f 00 00 00       	call   c01002d9 <cprintf>
    lab1_switch_to_user();
c010025a:	e8 c1 ff ff ff       	call   c0100220 <lab1_switch_to_user>
    lab1_print_cur_status();
c010025f:	e8 fa fe ff ff       	call   c010015e <lab1_print_cur_status>
    cprintf("+++ switch to kernel mode +++\n");
c0100264:	c7 04 24 88 90 10 c0 	movl   $0xc0109088,(%esp)
c010026b:	e8 69 00 00 00       	call   c01002d9 <cprintf>
    lab1_switch_to_kernel();
c0100270:	e8 bc ff ff ff       	call   c0100231 <lab1_switch_to_kernel>
    lab1_print_cur_status();
c0100275:	e8 e4 fe ff ff       	call   c010015e <lab1_print_cur_status>
}
c010027a:	90                   	nop
c010027b:	c9                   	leave  
c010027c:	c3                   	ret    

c010027d <cputch>:
/* *
 * cputch - writes a single character @c to stdout, and it will
 * increace the value of counter pointed by @cnt.
 * */
static void
cputch(int c, int *cnt) {
c010027d:	f3 0f 1e fb          	endbr32 
c0100281:	55                   	push   %ebp
c0100282:	89 e5                	mov    %esp,%ebp
c0100284:	83 ec 18             	sub    $0x18,%esp
    cons_putc(c);
c0100287:	8b 45 08             	mov    0x8(%ebp),%eax
c010028a:	89 04 24             	mov    %eax,(%esp)
c010028d:	e8 22 1c 00 00       	call   c0101eb4 <cons_putc>
    (*cnt) ++;
c0100292:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100295:	8b 00                	mov    (%eax),%eax
c0100297:	8d 50 01             	lea    0x1(%eax),%edx
c010029a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010029d:	89 10                	mov    %edx,(%eax)
}
c010029f:	90                   	nop
c01002a0:	c9                   	leave  
c01002a1:	c3                   	ret    

c01002a2 <vcprintf>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want cprintf() instead.
 * */
int
vcprintf(const char *fmt, va_list ap) {
c01002a2:	f3 0f 1e fb          	endbr32 
c01002a6:	55                   	push   %ebp
c01002a7:	89 e5                	mov    %esp,%ebp
c01002a9:	83 ec 28             	sub    $0x28,%esp
    int cnt = 0;
c01002ac:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    vprintfmt((void*)cputch, &cnt, fmt, ap);
c01002b3:	8b 45 0c             	mov    0xc(%ebp),%eax
c01002b6:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01002ba:	8b 45 08             	mov    0x8(%ebp),%eax
c01002bd:	89 44 24 08          	mov    %eax,0x8(%esp)
c01002c1:	8d 45 f4             	lea    -0xc(%ebp),%eax
c01002c4:	89 44 24 04          	mov    %eax,0x4(%esp)
c01002c8:	c7 04 24 7d 02 10 c0 	movl   $0xc010027d,(%esp)
c01002cf:	e8 85 87 00 00       	call   c0108a59 <vprintfmt>
    return cnt;
c01002d4:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01002d7:	c9                   	leave  
c01002d8:	c3                   	ret    

c01002d9 <cprintf>:
 *
 * The return value is the number of characters which would be
 * written to stdout.
 * */
int
cprintf(const char *fmt, ...) {
c01002d9:	f3 0f 1e fb          	endbr32 
c01002dd:	55                   	push   %ebp
c01002de:	89 e5                	mov    %esp,%ebp
c01002e0:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    int cnt;
    va_start(ap, fmt);
c01002e3:	8d 45 0c             	lea    0xc(%ebp),%eax
c01002e6:	89 45 f0             	mov    %eax,-0x10(%ebp)
    cnt = vcprintf(fmt, ap);
c01002e9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01002ec:	89 44 24 04          	mov    %eax,0x4(%esp)
c01002f0:	8b 45 08             	mov    0x8(%ebp),%eax
c01002f3:	89 04 24             	mov    %eax,(%esp)
c01002f6:	e8 a7 ff ff ff       	call   c01002a2 <vcprintf>
c01002fb:	89 45 f4             	mov    %eax,-0xc(%ebp)
    va_end(ap);
    return cnt;
c01002fe:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0100301:	c9                   	leave  
c0100302:	c3                   	ret    

c0100303 <cputchar>:

/* cputchar - writes a single character to stdout */
void
cputchar(int c) {
c0100303:	f3 0f 1e fb          	endbr32 
c0100307:	55                   	push   %ebp
c0100308:	89 e5                	mov    %esp,%ebp
c010030a:	83 ec 18             	sub    $0x18,%esp
    cons_putc(c);
c010030d:	8b 45 08             	mov    0x8(%ebp),%eax
c0100310:	89 04 24             	mov    %eax,(%esp)
c0100313:	e8 9c 1b 00 00       	call   c0101eb4 <cons_putc>
}
c0100318:	90                   	nop
c0100319:	c9                   	leave  
c010031a:	c3                   	ret    

c010031b <cputs>:
/* *
 * cputs- writes the string pointed by @str to stdout and
 * appends a newline character.
 * */
int
cputs(const char *str) {
c010031b:	f3 0f 1e fb          	endbr32 
c010031f:	55                   	push   %ebp
c0100320:	89 e5                	mov    %esp,%ebp
c0100322:	83 ec 28             	sub    $0x28,%esp
    int cnt = 0;
c0100325:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    char c;
    while ((c = *str ++) != '\0') {
c010032c:	eb 13                	jmp    c0100341 <cputs+0x26>
        cputch(c, &cnt);
c010032e:	0f be 45 f7          	movsbl -0x9(%ebp),%eax
c0100332:	8d 55 f0             	lea    -0x10(%ebp),%edx
c0100335:	89 54 24 04          	mov    %edx,0x4(%esp)
c0100339:	89 04 24             	mov    %eax,(%esp)
c010033c:	e8 3c ff ff ff       	call   c010027d <cputch>
    while ((c = *str ++) != '\0') {
c0100341:	8b 45 08             	mov    0x8(%ebp),%eax
c0100344:	8d 50 01             	lea    0x1(%eax),%edx
c0100347:	89 55 08             	mov    %edx,0x8(%ebp)
c010034a:	0f b6 00             	movzbl (%eax),%eax
c010034d:	88 45 f7             	mov    %al,-0x9(%ebp)
c0100350:	80 7d f7 00          	cmpb   $0x0,-0x9(%ebp)
c0100354:	75 d8                	jne    c010032e <cputs+0x13>
    }
    cputch('\n', &cnt);
c0100356:	8d 45 f0             	lea    -0x10(%ebp),%eax
c0100359:	89 44 24 04          	mov    %eax,0x4(%esp)
c010035d:	c7 04 24 0a 00 00 00 	movl   $0xa,(%esp)
c0100364:	e8 14 ff ff ff       	call   c010027d <cputch>
    return cnt;
c0100369:	8b 45 f0             	mov    -0x10(%ebp),%eax
}
c010036c:	c9                   	leave  
c010036d:	c3                   	ret    

c010036e <getchar>:

/* getchar - reads a single non-zero character from stdin */
int
getchar(void) {
c010036e:	f3 0f 1e fb          	endbr32 
c0100372:	55                   	push   %ebp
c0100373:	89 e5                	mov    %esp,%ebp
c0100375:	83 ec 18             	sub    $0x18,%esp
    int c;
    while ((c = cons_getc()) == 0)
c0100378:	90                   	nop
c0100379:	e8 77 1b 00 00       	call   c0101ef5 <cons_getc>
c010037e:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0100381:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0100385:	74 f2                	je     c0100379 <getchar+0xb>
        /* do nothing */;
    return c;
c0100387:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010038a:	c9                   	leave  
c010038b:	c3                   	ret    

c010038c <readline>:
 * The readline() function returns the text of the line read. If some errors
 * are happened, NULL is returned. The return value is a global variable,
 * thus it should be copied before it is used.
 * */
char *
readline(const char *prompt) {
c010038c:	f3 0f 1e fb          	endbr32 
c0100390:	55                   	push   %ebp
c0100391:	89 e5                	mov    %esp,%ebp
c0100393:	83 ec 28             	sub    $0x28,%esp
    if (prompt != NULL) {
c0100396:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c010039a:	74 13                	je     c01003af <readline+0x23>
        cprintf("%s", prompt);
c010039c:	8b 45 08             	mov    0x8(%ebp),%eax
c010039f:	89 44 24 04          	mov    %eax,0x4(%esp)
c01003a3:	c7 04 24 a7 90 10 c0 	movl   $0xc01090a7,(%esp)
c01003aa:	e8 2a ff ff ff       	call   c01002d9 <cprintf>
    }
    int i = 0, c;
c01003af:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    while (1) {
        c = getchar();
c01003b6:	e8 b3 ff ff ff       	call   c010036e <getchar>
c01003bb:	89 45 f0             	mov    %eax,-0x10(%ebp)
        if (c < 0) {
c01003be:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01003c2:	79 07                	jns    c01003cb <readline+0x3f>
            return NULL;
c01003c4:	b8 00 00 00 00       	mov    $0x0,%eax
c01003c9:	eb 78                	jmp    c0100443 <readline+0xb7>
        }
        else if (c >= ' ' && i < BUFSIZE - 1) {
c01003cb:	83 7d f0 1f          	cmpl   $0x1f,-0x10(%ebp)
c01003cf:	7e 28                	jle    c01003f9 <readline+0x6d>
c01003d1:	81 7d f4 fe 03 00 00 	cmpl   $0x3fe,-0xc(%ebp)
c01003d8:	7f 1f                	jg     c01003f9 <readline+0x6d>
            cputchar(c);
c01003da:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01003dd:	89 04 24             	mov    %eax,(%esp)
c01003e0:	e8 1e ff ff ff       	call   c0100303 <cputchar>
            buf[i ++] = c;
c01003e5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01003e8:	8d 50 01             	lea    0x1(%eax),%edx
c01003eb:	89 55 f4             	mov    %edx,-0xc(%ebp)
c01003ee:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01003f1:	88 90 20 60 12 c0    	mov    %dl,-0x3fed9fe0(%eax)
c01003f7:	eb 45                	jmp    c010043e <readline+0xb2>
        }
        else if (c == '\b' && i > 0) {
c01003f9:	83 7d f0 08          	cmpl   $0x8,-0x10(%ebp)
c01003fd:	75 16                	jne    c0100415 <readline+0x89>
c01003ff:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0100403:	7e 10                	jle    c0100415 <readline+0x89>
            cputchar(c);
c0100405:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100408:	89 04 24             	mov    %eax,(%esp)
c010040b:	e8 f3 fe ff ff       	call   c0100303 <cputchar>
            i --;
c0100410:	ff 4d f4             	decl   -0xc(%ebp)
c0100413:	eb 29                	jmp    c010043e <readline+0xb2>
        }
        else if (c == '\n' || c == '\r') {
c0100415:	83 7d f0 0a          	cmpl   $0xa,-0x10(%ebp)
c0100419:	74 06                	je     c0100421 <readline+0x95>
c010041b:	83 7d f0 0d          	cmpl   $0xd,-0x10(%ebp)
c010041f:	75 95                	jne    c01003b6 <readline+0x2a>
            cputchar(c);
c0100421:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100424:	89 04 24             	mov    %eax,(%esp)
c0100427:	e8 d7 fe ff ff       	call   c0100303 <cputchar>
            buf[i] = '\0';
c010042c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010042f:	05 20 60 12 c0       	add    $0xc0126020,%eax
c0100434:	c6 00 00             	movb   $0x0,(%eax)
            return buf;
c0100437:	b8 20 60 12 c0       	mov    $0xc0126020,%eax
c010043c:	eb 05                	jmp    c0100443 <readline+0xb7>
        c = getchar();
c010043e:	e9 73 ff ff ff       	jmp    c01003b6 <readline+0x2a>
        }
    }
}
c0100443:	c9                   	leave  
c0100444:	c3                   	ret    

c0100445 <__panic>:
/* *
 * __panic - __panic is called on unresolvable fatal errors. it prints
 * "panic: 'message'", and then enters the kernel monitor.
 * */
void
__panic(const char *file, int line, const char *fmt, ...) {
c0100445:	f3 0f 1e fb          	endbr32 
c0100449:	55                   	push   %ebp
c010044a:	89 e5                	mov    %esp,%ebp
c010044c:	83 ec 28             	sub    $0x28,%esp
    if (is_panic) {
c010044f:	a1 20 64 12 c0       	mov    0xc0126420,%eax
c0100454:	85 c0                	test   %eax,%eax
c0100456:	75 5b                	jne    c01004b3 <__panic+0x6e>
        goto panic_dead;
    }
    is_panic = 1;
c0100458:	c7 05 20 64 12 c0 01 	movl   $0x1,0xc0126420
c010045f:	00 00 00 

    // print the 'message'
    va_list ap;
    va_start(ap, fmt);
c0100462:	8d 45 14             	lea    0x14(%ebp),%eax
c0100465:	89 45 f4             	mov    %eax,-0xc(%ebp)
    cprintf("kernel panic at %s:%d:\n    ", file, line);
c0100468:	8b 45 0c             	mov    0xc(%ebp),%eax
c010046b:	89 44 24 08          	mov    %eax,0x8(%esp)
c010046f:	8b 45 08             	mov    0x8(%ebp),%eax
c0100472:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100476:	c7 04 24 aa 90 10 c0 	movl   $0xc01090aa,(%esp)
c010047d:	e8 57 fe ff ff       	call   c01002d9 <cprintf>
    vcprintf(fmt, ap);
c0100482:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100485:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100489:	8b 45 10             	mov    0x10(%ebp),%eax
c010048c:	89 04 24             	mov    %eax,(%esp)
c010048f:	e8 0e fe ff ff       	call   c01002a2 <vcprintf>
    cprintf("\n");
c0100494:	c7 04 24 c6 90 10 c0 	movl   $0xc01090c6,(%esp)
c010049b:	e8 39 fe ff ff       	call   c01002d9 <cprintf>
    
    cprintf("stack trackback:\n");
c01004a0:	c7 04 24 c8 90 10 c0 	movl   $0xc01090c8,(%esp)
c01004a7:	e8 2d fe ff ff       	call   c01002d9 <cprintf>
    print_stackframe();
c01004ac:	e8 3d 06 00 00       	call   c0100aee <print_stackframe>
c01004b1:	eb 01                	jmp    c01004b4 <__panic+0x6f>
        goto panic_dead;
c01004b3:	90                   	nop
    
    va_end(ap);

panic_dead:
    intr_disable();
c01004b4:	e8 9d 1c 00 00       	call   c0102156 <intr_disable>
    while (1) {
        kmonitor(NULL);
c01004b9:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c01004c0:	e8 a7 07 00 00       	call   c0100c6c <kmonitor>
c01004c5:	eb f2                	jmp    c01004b9 <__panic+0x74>

c01004c7 <__warn>:
    }
}

/* __warn - like panic, but don't */
void
__warn(const char *file, int line, const char *fmt, ...) {
c01004c7:	f3 0f 1e fb          	endbr32 
c01004cb:	55                   	push   %ebp
c01004cc:	89 e5                	mov    %esp,%ebp
c01004ce:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    va_start(ap, fmt);
c01004d1:	8d 45 14             	lea    0x14(%ebp),%eax
c01004d4:	89 45 f4             	mov    %eax,-0xc(%ebp)
    cprintf("kernel warning at %s:%d:\n    ", file, line);
c01004d7:	8b 45 0c             	mov    0xc(%ebp),%eax
c01004da:	89 44 24 08          	mov    %eax,0x8(%esp)
c01004de:	8b 45 08             	mov    0x8(%ebp),%eax
c01004e1:	89 44 24 04          	mov    %eax,0x4(%esp)
c01004e5:	c7 04 24 da 90 10 c0 	movl   $0xc01090da,(%esp)
c01004ec:	e8 e8 fd ff ff       	call   c01002d9 <cprintf>
    vcprintf(fmt, ap);
c01004f1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01004f4:	89 44 24 04          	mov    %eax,0x4(%esp)
c01004f8:	8b 45 10             	mov    0x10(%ebp),%eax
c01004fb:	89 04 24             	mov    %eax,(%esp)
c01004fe:	e8 9f fd ff ff       	call   c01002a2 <vcprintf>
    cprintf("\n");
c0100503:	c7 04 24 c6 90 10 c0 	movl   $0xc01090c6,(%esp)
c010050a:	e8 ca fd ff ff       	call   c01002d9 <cprintf>
    va_end(ap);
}
c010050f:	90                   	nop
c0100510:	c9                   	leave  
c0100511:	c3                   	ret    

c0100512 <is_kernel_panic>:

bool
is_kernel_panic(void) {
c0100512:	f3 0f 1e fb          	endbr32 
c0100516:	55                   	push   %ebp
c0100517:	89 e5                	mov    %esp,%ebp
    return is_panic;
c0100519:	a1 20 64 12 c0       	mov    0xc0126420,%eax
}
c010051e:	5d                   	pop    %ebp
c010051f:	c3                   	ret    

c0100520 <stab_binsearch>:
 *      stab_binsearch(stabs, &left, &right, N_SO, 0xf0100184);
 * will exit setting left = 118, right = 554.
 * */
static void
stab_binsearch(const struct stab *stabs, int *region_left, int *region_right,
           int type, uintptr_t addr) {
c0100520:	f3 0f 1e fb          	endbr32 
c0100524:	55                   	push   %ebp
c0100525:	89 e5                	mov    %esp,%ebp
c0100527:	83 ec 20             	sub    $0x20,%esp
    int l = *region_left, r = *region_right, any_matches = 0;
c010052a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010052d:	8b 00                	mov    (%eax),%eax
c010052f:	89 45 fc             	mov    %eax,-0x4(%ebp)
c0100532:	8b 45 10             	mov    0x10(%ebp),%eax
c0100535:	8b 00                	mov    (%eax),%eax
c0100537:	89 45 f8             	mov    %eax,-0x8(%ebp)
c010053a:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)

    while (l <= r) {
c0100541:	e9 ca 00 00 00       	jmp    c0100610 <stab_binsearch+0xf0>
        int true_m = (l + r) / 2, m = true_m;
c0100546:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0100549:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010054c:	01 d0                	add    %edx,%eax
c010054e:	89 c2                	mov    %eax,%edx
c0100550:	c1 ea 1f             	shr    $0x1f,%edx
c0100553:	01 d0                	add    %edx,%eax
c0100555:	d1 f8                	sar    %eax
c0100557:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010055a:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010055d:	89 45 f0             	mov    %eax,-0x10(%ebp)

        // search for earliest stab with right type
        while (m >= l && stabs[m].n_type != type) {
c0100560:	eb 03                	jmp    c0100565 <stab_binsearch+0x45>
            m --;
c0100562:	ff 4d f0             	decl   -0x10(%ebp)
        while (m >= l && stabs[m].n_type != type) {
c0100565:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100568:	3b 45 fc             	cmp    -0x4(%ebp),%eax
c010056b:	7c 1f                	jl     c010058c <stab_binsearch+0x6c>
c010056d:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0100570:	89 d0                	mov    %edx,%eax
c0100572:	01 c0                	add    %eax,%eax
c0100574:	01 d0                	add    %edx,%eax
c0100576:	c1 e0 02             	shl    $0x2,%eax
c0100579:	89 c2                	mov    %eax,%edx
c010057b:	8b 45 08             	mov    0x8(%ebp),%eax
c010057e:	01 d0                	add    %edx,%eax
c0100580:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c0100584:	0f b6 c0             	movzbl %al,%eax
c0100587:	39 45 14             	cmp    %eax,0x14(%ebp)
c010058a:	75 d6                	jne    c0100562 <stab_binsearch+0x42>
        }
        if (m < l) {    // no match in [l, m]
c010058c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010058f:	3b 45 fc             	cmp    -0x4(%ebp),%eax
c0100592:	7d 09                	jge    c010059d <stab_binsearch+0x7d>
            l = true_m + 1;
c0100594:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100597:	40                   	inc    %eax
c0100598:	89 45 fc             	mov    %eax,-0x4(%ebp)
            continue;
c010059b:	eb 73                	jmp    c0100610 <stab_binsearch+0xf0>
        }

        // actual binary search
        any_matches = 1;
c010059d:	c7 45 f4 01 00 00 00 	movl   $0x1,-0xc(%ebp)
        if (stabs[m].n_value < addr) {
c01005a4:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01005a7:	89 d0                	mov    %edx,%eax
c01005a9:	01 c0                	add    %eax,%eax
c01005ab:	01 d0                	add    %edx,%eax
c01005ad:	c1 e0 02             	shl    $0x2,%eax
c01005b0:	89 c2                	mov    %eax,%edx
c01005b2:	8b 45 08             	mov    0x8(%ebp),%eax
c01005b5:	01 d0                	add    %edx,%eax
c01005b7:	8b 40 08             	mov    0x8(%eax),%eax
c01005ba:	39 45 18             	cmp    %eax,0x18(%ebp)
c01005bd:	76 11                	jbe    c01005d0 <stab_binsearch+0xb0>
            *region_left = m;
c01005bf:	8b 45 0c             	mov    0xc(%ebp),%eax
c01005c2:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01005c5:	89 10                	mov    %edx,(%eax)
            l = true_m + 1;
c01005c7:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01005ca:	40                   	inc    %eax
c01005cb:	89 45 fc             	mov    %eax,-0x4(%ebp)
c01005ce:	eb 40                	jmp    c0100610 <stab_binsearch+0xf0>
        } else if (stabs[m].n_value > addr) {
c01005d0:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01005d3:	89 d0                	mov    %edx,%eax
c01005d5:	01 c0                	add    %eax,%eax
c01005d7:	01 d0                	add    %edx,%eax
c01005d9:	c1 e0 02             	shl    $0x2,%eax
c01005dc:	89 c2                	mov    %eax,%edx
c01005de:	8b 45 08             	mov    0x8(%ebp),%eax
c01005e1:	01 d0                	add    %edx,%eax
c01005e3:	8b 40 08             	mov    0x8(%eax),%eax
c01005e6:	39 45 18             	cmp    %eax,0x18(%ebp)
c01005e9:	73 14                	jae    c01005ff <stab_binsearch+0xdf>
            *region_right = m - 1;
c01005eb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01005ee:	8d 50 ff             	lea    -0x1(%eax),%edx
c01005f1:	8b 45 10             	mov    0x10(%ebp),%eax
c01005f4:	89 10                	mov    %edx,(%eax)
            r = m - 1;
c01005f6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01005f9:	48                   	dec    %eax
c01005fa:	89 45 f8             	mov    %eax,-0x8(%ebp)
c01005fd:	eb 11                	jmp    c0100610 <stab_binsearch+0xf0>
        } else {
            // exact match for 'addr', but continue loop to find
            // *region_right
            *region_left = m;
c01005ff:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100602:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0100605:	89 10                	mov    %edx,(%eax)
            l = m;
c0100607:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010060a:	89 45 fc             	mov    %eax,-0x4(%ebp)
            addr ++;
c010060d:	ff 45 18             	incl   0x18(%ebp)
    while (l <= r) {
c0100610:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100613:	3b 45 f8             	cmp    -0x8(%ebp),%eax
c0100616:	0f 8e 2a ff ff ff    	jle    c0100546 <stab_binsearch+0x26>
        }
    }

    if (!any_matches) {
c010061c:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0100620:	75 0f                	jne    c0100631 <stab_binsearch+0x111>
        *region_right = *region_left - 1;
c0100622:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100625:	8b 00                	mov    (%eax),%eax
c0100627:	8d 50 ff             	lea    -0x1(%eax),%edx
c010062a:	8b 45 10             	mov    0x10(%ebp),%eax
c010062d:	89 10                	mov    %edx,(%eax)
        l = *region_right;
        for (; l > *region_left && stabs[l].n_type != type; l --)
            /* do nothing */;
        *region_left = l;
    }
}
c010062f:	eb 3e                	jmp    c010066f <stab_binsearch+0x14f>
        l = *region_right;
c0100631:	8b 45 10             	mov    0x10(%ebp),%eax
c0100634:	8b 00                	mov    (%eax),%eax
c0100636:	89 45 fc             	mov    %eax,-0x4(%ebp)
        for (; l > *region_left && stabs[l].n_type != type; l --)
c0100639:	eb 03                	jmp    c010063e <stab_binsearch+0x11e>
c010063b:	ff 4d fc             	decl   -0x4(%ebp)
c010063e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100641:	8b 00                	mov    (%eax),%eax
c0100643:	39 45 fc             	cmp    %eax,-0x4(%ebp)
c0100646:	7e 1f                	jle    c0100667 <stab_binsearch+0x147>
c0100648:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010064b:	89 d0                	mov    %edx,%eax
c010064d:	01 c0                	add    %eax,%eax
c010064f:	01 d0                	add    %edx,%eax
c0100651:	c1 e0 02             	shl    $0x2,%eax
c0100654:	89 c2                	mov    %eax,%edx
c0100656:	8b 45 08             	mov    0x8(%ebp),%eax
c0100659:	01 d0                	add    %edx,%eax
c010065b:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c010065f:	0f b6 c0             	movzbl %al,%eax
c0100662:	39 45 14             	cmp    %eax,0x14(%ebp)
c0100665:	75 d4                	jne    c010063b <stab_binsearch+0x11b>
        *region_left = l;
c0100667:	8b 45 0c             	mov    0xc(%ebp),%eax
c010066a:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010066d:	89 10                	mov    %edx,(%eax)
}
c010066f:	90                   	nop
c0100670:	c9                   	leave  
c0100671:	c3                   	ret    

c0100672 <debuginfo_eip>:
 * the specified instruction address, @addr.  Returns 0 if information
 * was found, and negative if not.  But even if it returns negative it
 * has stored some information into '*info'.
 * */
int
debuginfo_eip(uintptr_t addr, struct eipdebuginfo *info) {
c0100672:	f3 0f 1e fb          	endbr32 
c0100676:	55                   	push   %ebp
c0100677:	89 e5                	mov    %esp,%ebp
c0100679:	83 ec 58             	sub    $0x58,%esp
    const struct stab *stabs, *stab_end;
    const char *stabstr, *stabstr_end;

    info->eip_file = "<unknown>";
c010067c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010067f:	c7 00 f8 90 10 c0    	movl   $0xc01090f8,(%eax)
    info->eip_line = 0;
c0100685:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100688:	c7 40 04 00 00 00 00 	movl   $0x0,0x4(%eax)
    info->eip_fn_name = "<unknown>";
c010068f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100692:	c7 40 08 f8 90 10 c0 	movl   $0xc01090f8,0x8(%eax)
    info->eip_fn_namelen = 9;
c0100699:	8b 45 0c             	mov    0xc(%ebp),%eax
c010069c:	c7 40 0c 09 00 00 00 	movl   $0x9,0xc(%eax)
    info->eip_fn_addr = addr;
c01006a3:	8b 45 0c             	mov    0xc(%ebp),%eax
c01006a6:	8b 55 08             	mov    0x8(%ebp),%edx
c01006a9:	89 50 10             	mov    %edx,0x10(%eax)
    info->eip_fn_narg = 0;
c01006ac:	8b 45 0c             	mov    0xc(%ebp),%eax
c01006af:	c7 40 14 00 00 00 00 	movl   $0x0,0x14(%eax)

    stabs = __STAB_BEGIN__;
c01006b6:	c7 45 f4 60 b0 10 c0 	movl   $0xc010b060,-0xc(%ebp)
    stab_end = __STAB_END__;
c01006bd:	c7 45 f0 e4 ca 11 c0 	movl   $0xc011cae4,-0x10(%ebp)
    stabstr = __STABSTR_BEGIN__;
c01006c4:	c7 45 ec e5 ca 11 c0 	movl   $0xc011cae5,-0x14(%ebp)
    stabstr_end = __STABSTR_END__;
c01006cb:	c7 45 e8 86 04 12 c0 	movl   $0xc0120486,-0x18(%ebp)

    // String table validity checks
    if (stabstr_end <= stabstr || stabstr_end[-1] != 0) {
c01006d2:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01006d5:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c01006d8:	76 0b                	jbe    c01006e5 <debuginfo_eip+0x73>
c01006da:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01006dd:	48                   	dec    %eax
c01006de:	0f b6 00             	movzbl (%eax),%eax
c01006e1:	84 c0                	test   %al,%al
c01006e3:	74 0a                	je     c01006ef <debuginfo_eip+0x7d>
        return -1;
c01006e5:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c01006ea:	e9 ab 02 00 00       	jmp    c010099a <debuginfo_eip+0x328>
    // 'eip'.  First, we find the basic source file containing 'eip'.
    // Then, we look in that source file for the function.  Then we look
    // for the line number.

    // Search the entire set of stabs for the source file (type N_SO).
    int lfile = 0, rfile = (stab_end - stabs) - 1;
c01006ef:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
c01006f6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01006f9:	2b 45 f4             	sub    -0xc(%ebp),%eax
c01006fc:	c1 f8 02             	sar    $0x2,%eax
c01006ff:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
c0100705:	48                   	dec    %eax
c0100706:	89 45 e0             	mov    %eax,-0x20(%ebp)
    stab_binsearch(stabs, &lfile, &rfile, N_SO, addr);
c0100709:	8b 45 08             	mov    0x8(%ebp),%eax
c010070c:	89 44 24 10          	mov    %eax,0x10(%esp)
c0100710:	c7 44 24 0c 64 00 00 	movl   $0x64,0xc(%esp)
c0100717:	00 
c0100718:	8d 45 e0             	lea    -0x20(%ebp),%eax
c010071b:	89 44 24 08          	mov    %eax,0x8(%esp)
c010071f:	8d 45 e4             	lea    -0x1c(%ebp),%eax
c0100722:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100726:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100729:	89 04 24             	mov    %eax,(%esp)
c010072c:	e8 ef fd ff ff       	call   c0100520 <stab_binsearch>
    if (lfile == 0)
c0100731:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100734:	85 c0                	test   %eax,%eax
c0100736:	75 0a                	jne    c0100742 <debuginfo_eip+0xd0>
        return -1;
c0100738:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c010073d:	e9 58 02 00 00       	jmp    c010099a <debuginfo_eip+0x328>

    // Search within that file's stabs for the function definition
    // (N_FUN).
    int lfun = lfile, rfun = rfile;
c0100742:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100745:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0100748:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010074b:	89 45 d8             	mov    %eax,-0x28(%ebp)
    int lline, rline;
    stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr);
c010074e:	8b 45 08             	mov    0x8(%ebp),%eax
c0100751:	89 44 24 10          	mov    %eax,0x10(%esp)
c0100755:	c7 44 24 0c 24 00 00 	movl   $0x24,0xc(%esp)
c010075c:	00 
c010075d:	8d 45 d8             	lea    -0x28(%ebp),%eax
c0100760:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100764:	8d 45 dc             	lea    -0x24(%ebp),%eax
c0100767:	89 44 24 04          	mov    %eax,0x4(%esp)
c010076b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010076e:	89 04 24             	mov    %eax,(%esp)
c0100771:	e8 aa fd ff ff       	call   c0100520 <stab_binsearch>

    if (lfun <= rfun) {
c0100776:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0100779:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010077c:	39 c2                	cmp    %eax,%edx
c010077e:	7f 78                	jg     c01007f8 <debuginfo_eip+0x186>
        // stabs[lfun] points to the function name
        // in the string table, but check bounds just in case.
        if (stabs[lfun].n_strx < stabstr_end - stabstr) {
c0100780:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0100783:	89 c2                	mov    %eax,%edx
c0100785:	89 d0                	mov    %edx,%eax
c0100787:	01 c0                	add    %eax,%eax
c0100789:	01 d0                	add    %edx,%eax
c010078b:	c1 e0 02             	shl    $0x2,%eax
c010078e:	89 c2                	mov    %eax,%edx
c0100790:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100793:	01 d0                	add    %edx,%eax
c0100795:	8b 10                	mov    (%eax),%edx
c0100797:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010079a:	2b 45 ec             	sub    -0x14(%ebp),%eax
c010079d:	39 c2                	cmp    %eax,%edx
c010079f:	73 22                	jae    c01007c3 <debuginfo_eip+0x151>
            info->eip_fn_name = stabstr + stabs[lfun].n_strx;
c01007a1:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01007a4:	89 c2                	mov    %eax,%edx
c01007a6:	89 d0                	mov    %edx,%eax
c01007a8:	01 c0                	add    %eax,%eax
c01007aa:	01 d0                	add    %edx,%eax
c01007ac:	c1 e0 02             	shl    $0x2,%eax
c01007af:	89 c2                	mov    %eax,%edx
c01007b1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01007b4:	01 d0                	add    %edx,%eax
c01007b6:	8b 10                	mov    (%eax),%edx
c01007b8:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01007bb:	01 c2                	add    %eax,%edx
c01007bd:	8b 45 0c             	mov    0xc(%ebp),%eax
c01007c0:	89 50 08             	mov    %edx,0x8(%eax)
        }
        info->eip_fn_addr = stabs[lfun].n_value;
c01007c3:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01007c6:	89 c2                	mov    %eax,%edx
c01007c8:	89 d0                	mov    %edx,%eax
c01007ca:	01 c0                	add    %eax,%eax
c01007cc:	01 d0                	add    %edx,%eax
c01007ce:	c1 e0 02             	shl    $0x2,%eax
c01007d1:	89 c2                	mov    %eax,%edx
c01007d3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01007d6:	01 d0                	add    %edx,%eax
c01007d8:	8b 50 08             	mov    0x8(%eax),%edx
c01007db:	8b 45 0c             	mov    0xc(%ebp),%eax
c01007de:	89 50 10             	mov    %edx,0x10(%eax)
        addr -= info->eip_fn_addr;
c01007e1:	8b 45 0c             	mov    0xc(%ebp),%eax
c01007e4:	8b 40 10             	mov    0x10(%eax),%eax
c01007e7:	29 45 08             	sub    %eax,0x8(%ebp)
        // Search within the function definition for the line number.
        lline = lfun;
c01007ea:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01007ed:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        rline = rfun;
c01007f0:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01007f3:	89 45 d0             	mov    %eax,-0x30(%ebp)
c01007f6:	eb 15                	jmp    c010080d <debuginfo_eip+0x19b>
    } else {
        // Couldn't find function stab!  Maybe we're in an assembly
        // file.  Search the whole file for the line number.
        info->eip_fn_addr = addr;
c01007f8:	8b 45 0c             	mov    0xc(%ebp),%eax
c01007fb:	8b 55 08             	mov    0x8(%ebp),%edx
c01007fe:	89 50 10             	mov    %edx,0x10(%eax)
        lline = lfile;
c0100801:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100804:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        rline = rfile;
c0100807:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010080a:	89 45 d0             	mov    %eax,-0x30(%ebp)
    }
    info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name;
c010080d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100810:	8b 40 08             	mov    0x8(%eax),%eax
c0100813:	c7 44 24 04 3a 00 00 	movl   $0x3a,0x4(%esp)
c010081a:	00 
c010081b:	89 04 24             	mov    %eax,(%esp)
c010081e:	e8 3e 7d 00 00       	call   c0108561 <strfind>
c0100823:	8b 55 0c             	mov    0xc(%ebp),%edx
c0100826:	8b 52 08             	mov    0x8(%edx),%edx
c0100829:	29 d0                	sub    %edx,%eax
c010082b:	89 c2                	mov    %eax,%edx
c010082d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100830:	89 50 0c             	mov    %edx,0xc(%eax)

    // Search within [lline, rline] for the line number stab.
    // If found, set info->eip_line to the right line number.
    // If not found, return -1.
    stab_binsearch(stabs, &lline, &rline, N_SLINE, addr);
c0100833:	8b 45 08             	mov    0x8(%ebp),%eax
c0100836:	89 44 24 10          	mov    %eax,0x10(%esp)
c010083a:	c7 44 24 0c 44 00 00 	movl   $0x44,0xc(%esp)
c0100841:	00 
c0100842:	8d 45 d0             	lea    -0x30(%ebp),%eax
c0100845:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100849:	8d 45 d4             	lea    -0x2c(%ebp),%eax
c010084c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100850:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100853:	89 04 24             	mov    %eax,(%esp)
c0100856:	e8 c5 fc ff ff       	call   c0100520 <stab_binsearch>
    if (lline <= rline) {
c010085b:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010085e:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0100861:	39 c2                	cmp    %eax,%edx
c0100863:	7f 23                	jg     c0100888 <debuginfo_eip+0x216>
        info->eip_line = stabs[rline].n_desc;
c0100865:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0100868:	89 c2                	mov    %eax,%edx
c010086a:	89 d0                	mov    %edx,%eax
c010086c:	01 c0                	add    %eax,%eax
c010086e:	01 d0                	add    %edx,%eax
c0100870:	c1 e0 02             	shl    $0x2,%eax
c0100873:	89 c2                	mov    %eax,%edx
c0100875:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100878:	01 d0                	add    %edx,%eax
c010087a:	0f b7 40 06          	movzwl 0x6(%eax),%eax
c010087e:	89 c2                	mov    %eax,%edx
c0100880:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100883:	89 50 04             	mov    %edx,0x4(%eax)

    // Search backwards from the line number for the relevant filename stab.
    // We can't just use the "lfile" stab because inlined functions
    // can interpolate code from a different file!
    // Such included source files use the N_SOL stab type.
    while (lline >= lfile
c0100886:	eb 11                	jmp    c0100899 <debuginfo_eip+0x227>
        return -1;
c0100888:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c010088d:	e9 08 01 00 00       	jmp    c010099a <debuginfo_eip+0x328>
           && stabs[lline].n_type != N_SOL
           && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) {
        lline --;
c0100892:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100895:	48                   	dec    %eax
c0100896:	89 45 d4             	mov    %eax,-0x2c(%ebp)
    while (lline >= lfile
c0100899:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010089c:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010089f:	39 c2                	cmp    %eax,%edx
c01008a1:	7c 56                	jl     c01008f9 <debuginfo_eip+0x287>
           && stabs[lline].n_type != N_SOL
c01008a3:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01008a6:	89 c2                	mov    %eax,%edx
c01008a8:	89 d0                	mov    %edx,%eax
c01008aa:	01 c0                	add    %eax,%eax
c01008ac:	01 d0                	add    %edx,%eax
c01008ae:	c1 e0 02             	shl    $0x2,%eax
c01008b1:	89 c2                	mov    %eax,%edx
c01008b3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01008b6:	01 d0                	add    %edx,%eax
c01008b8:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c01008bc:	3c 84                	cmp    $0x84,%al
c01008be:	74 39                	je     c01008f9 <debuginfo_eip+0x287>
           && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) {
c01008c0:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01008c3:	89 c2                	mov    %eax,%edx
c01008c5:	89 d0                	mov    %edx,%eax
c01008c7:	01 c0                	add    %eax,%eax
c01008c9:	01 d0                	add    %edx,%eax
c01008cb:	c1 e0 02             	shl    $0x2,%eax
c01008ce:	89 c2                	mov    %eax,%edx
c01008d0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01008d3:	01 d0                	add    %edx,%eax
c01008d5:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c01008d9:	3c 64                	cmp    $0x64,%al
c01008db:	75 b5                	jne    c0100892 <debuginfo_eip+0x220>
c01008dd:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01008e0:	89 c2                	mov    %eax,%edx
c01008e2:	89 d0                	mov    %edx,%eax
c01008e4:	01 c0                	add    %eax,%eax
c01008e6:	01 d0                	add    %edx,%eax
c01008e8:	c1 e0 02             	shl    $0x2,%eax
c01008eb:	89 c2                	mov    %eax,%edx
c01008ed:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01008f0:	01 d0                	add    %edx,%eax
c01008f2:	8b 40 08             	mov    0x8(%eax),%eax
c01008f5:	85 c0                	test   %eax,%eax
c01008f7:	74 99                	je     c0100892 <debuginfo_eip+0x220>
    }
    if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) {
c01008f9:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01008fc:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01008ff:	39 c2                	cmp    %eax,%edx
c0100901:	7c 42                	jl     c0100945 <debuginfo_eip+0x2d3>
c0100903:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100906:	89 c2                	mov    %eax,%edx
c0100908:	89 d0                	mov    %edx,%eax
c010090a:	01 c0                	add    %eax,%eax
c010090c:	01 d0                	add    %edx,%eax
c010090e:	c1 e0 02             	shl    $0x2,%eax
c0100911:	89 c2                	mov    %eax,%edx
c0100913:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100916:	01 d0                	add    %edx,%eax
c0100918:	8b 10                	mov    (%eax),%edx
c010091a:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010091d:	2b 45 ec             	sub    -0x14(%ebp),%eax
c0100920:	39 c2                	cmp    %eax,%edx
c0100922:	73 21                	jae    c0100945 <debuginfo_eip+0x2d3>
        info->eip_file = stabstr + stabs[lline].n_strx;
c0100924:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100927:	89 c2                	mov    %eax,%edx
c0100929:	89 d0                	mov    %edx,%eax
c010092b:	01 c0                	add    %eax,%eax
c010092d:	01 d0                	add    %edx,%eax
c010092f:	c1 e0 02             	shl    $0x2,%eax
c0100932:	89 c2                	mov    %eax,%edx
c0100934:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100937:	01 d0                	add    %edx,%eax
c0100939:	8b 10                	mov    (%eax),%edx
c010093b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010093e:	01 c2                	add    %eax,%edx
c0100940:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100943:	89 10                	mov    %edx,(%eax)
    }

    // Set eip_fn_narg to the number of arguments taken by the function,
    // or 0 if there was no containing function.
    if (lfun < rfun) {
c0100945:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0100948:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010094b:	39 c2                	cmp    %eax,%edx
c010094d:	7d 46                	jge    c0100995 <debuginfo_eip+0x323>
        for (lline = lfun + 1;
c010094f:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0100952:	40                   	inc    %eax
c0100953:	89 45 d4             	mov    %eax,-0x2c(%ebp)
c0100956:	eb 16                	jmp    c010096e <debuginfo_eip+0x2fc>
             lline < rfun && stabs[lline].n_type == N_PSYM;
             lline ++) {
            info->eip_fn_narg ++;
c0100958:	8b 45 0c             	mov    0xc(%ebp),%eax
c010095b:	8b 40 14             	mov    0x14(%eax),%eax
c010095e:	8d 50 01             	lea    0x1(%eax),%edx
c0100961:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100964:	89 50 14             	mov    %edx,0x14(%eax)
             lline ++) {
c0100967:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c010096a:	40                   	inc    %eax
c010096b:	89 45 d4             	mov    %eax,-0x2c(%ebp)
             lline < rfun && stabs[lline].n_type == N_PSYM;
c010096e:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0100971:	8b 45 d8             	mov    -0x28(%ebp),%eax
        for (lline = lfun + 1;
c0100974:	39 c2                	cmp    %eax,%edx
c0100976:	7d 1d                	jge    c0100995 <debuginfo_eip+0x323>
             lline < rfun && stabs[lline].n_type == N_PSYM;
c0100978:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c010097b:	89 c2                	mov    %eax,%edx
c010097d:	89 d0                	mov    %edx,%eax
c010097f:	01 c0                	add    %eax,%eax
c0100981:	01 d0                	add    %edx,%eax
c0100983:	c1 e0 02             	shl    $0x2,%eax
c0100986:	89 c2                	mov    %eax,%edx
c0100988:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010098b:	01 d0                	add    %edx,%eax
c010098d:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c0100991:	3c a0                	cmp    $0xa0,%al
c0100993:	74 c3                	je     c0100958 <debuginfo_eip+0x2e6>
        }
    }
    return 0;
c0100995:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010099a:	c9                   	leave  
c010099b:	c3                   	ret    

c010099c <print_kerninfo>:
 * print_kerninfo - print the information about kernel, including the location
 * of kernel entry, the start addresses of data and text segements, the start
 * address of free memory and how many memory that kernel has used.
 * */
void
print_kerninfo(void) {
c010099c:	f3 0f 1e fb          	endbr32 
c01009a0:	55                   	push   %ebp
c01009a1:	89 e5                	mov    %esp,%ebp
c01009a3:	83 ec 18             	sub    $0x18,%esp
    extern char etext[], edata[], end[], kern_init[];
    cprintf("Special kernel symbols:\n");
c01009a6:	c7 04 24 02 91 10 c0 	movl   $0xc0109102,(%esp)
c01009ad:	e8 27 f9 ff ff       	call   c01002d9 <cprintf>
    cprintf("  entry  0x%08x (phys)\n", kern_init);
c01009b2:	c7 44 24 04 36 00 10 	movl   $0xc0100036,0x4(%esp)
c01009b9:	c0 
c01009ba:	c7 04 24 1b 91 10 c0 	movl   $0xc010911b,(%esp)
c01009c1:	e8 13 f9 ff ff       	call   c01002d9 <cprintf>
    cprintf("  etext  0x%08x (phys)\n", etext);
c01009c6:	c7 44 24 04 f1 8f 10 	movl   $0xc0108ff1,0x4(%esp)
c01009cd:	c0 
c01009ce:	c7 04 24 33 91 10 c0 	movl   $0xc0109133,(%esp)
c01009d5:	e8 ff f8 ff ff       	call   c01002d9 <cprintf>
    cprintf("  edata  0x%08x (phys)\n", edata);
c01009da:	c7 44 24 04 00 60 12 	movl   $0xc0126000,0x4(%esp)
c01009e1:	c0 
c01009e2:	c7 04 24 4b 91 10 c0 	movl   $0xc010914b,(%esp)
c01009e9:	e8 eb f8 ff ff       	call   c01002d9 <cprintf>
    cprintf("  end    0x%08x (phys)\n", end);
c01009ee:	c7 44 24 04 70 71 12 	movl   $0xc0127170,0x4(%esp)
c01009f5:	c0 
c01009f6:	c7 04 24 63 91 10 c0 	movl   $0xc0109163,(%esp)
c01009fd:	e8 d7 f8 ff ff       	call   c01002d9 <cprintf>
    cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024);
c0100a02:	b8 70 71 12 c0       	mov    $0xc0127170,%eax
c0100a07:	2d 36 00 10 c0       	sub    $0xc0100036,%eax
c0100a0c:	05 ff 03 00 00       	add    $0x3ff,%eax
c0100a11:	8d 90 ff 03 00 00    	lea    0x3ff(%eax),%edx
c0100a17:	85 c0                	test   %eax,%eax
c0100a19:	0f 48 c2             	cmovs  %edx,%eax
c0100a1c:	c1 f8 0a             	sar    $0xa,%eax
c0100a1f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100a23:	c7 04 24 7c 91 10 c0 	movl   $0xc010917c,(%esp)
c0100a2a:	e8 aa f8 ff ff       	call   c01002d9 <cprintf>
}
c0100a2f:	90                   	nop
c0100a30:	c9                   	leave  
c0100a31:	c3                   	ret    

c0100a32 <print_debuginfo>:
/* *
 * print_debuginfo - read and print the stat information for the address @eip,
 * and info.eip_fn_addr should be the first address of the related function.
 * */
void
print_debuginfo(uintptr_t eip) {
c0100a32:	f3 0f 1e fb          	endbr32 
c0100a36:	55                   	push   %ebp
c0100a37:	89 e5                	mov    %esp,%ebp
c0100a39:	81 ec 48 01 00 00    	sub    $0x148,%esp
    struct eipdebuginfo info;
    if (debuginfo_eip(eip, &info) != 0) {
c0100a3f:	8d 45 dc             	lea    -0x24(%ebp),%eax
c0100a42:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100a46:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a49:	89 04 24             	mov    %eax,(%esp)
c0100a4c:	e8 21 fc ff ff       	call   c0100672 <debuginfo_eip>
c0100a51:	85 c0                	test   %eax,%eax
c0100a53:	74 15                	je     c0100a6a <print_debuginfo+0x38>
        cprintf("    <unknow>: -- 0x%08x --\n", eip);
c0100a55:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a58:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100a5c:	c7 04 24 a6 91 10 c0 	movl   $0xc01091a6,(%esp)
c0100a63:	e8 71 f8 ff ff       	call   c01002d9 <cprintf>
        }
        fnname[j] = '\0';
        cprintf("    %s:%d: %s+%d\n", info.eip_file, info.eip_line,
                fnname, eip - info.eip_fn_addr);
    }
}
c0100a68:	eb 6c                	jmp    c0100ad6 <print_debuginfo+0xa4>
        for (j = 0; j < info.eip_fn_namelen; j ++) {
c0100a6a:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0100a71:	eb 1b                	jmp    c0100a8e <print_debuginfo+0x5c>
            fnname[j] = info.eip_fn_name[j];
c0100a73:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0100a76:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100a79:	01 d0                	add    %edx,%eax
c0100a7b:	0f b6 10             	movzbl (%eax),%edx
c0100a7e:	8d 8d dc fe ff ff    	lea    -0x124(%ebp),%ecx
c0100a84:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100a87:	01 c8                	add    %ecx,%eax
c0100a89:	88 10                	mov    %dl,(%eax)
        for (j = 0; j < info.eip_fn_namelen; j ++) {
c0100a8b:	ff 45 f4             	incl   -0xc(%ebp)
c0100a8e:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0100a91:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0100a94:	7c dd                	jl     c0100a73 <print_debuginfo+0x41>
        fnname[j] = '\0';
c0100a96:	8d 95 dc fe ff ff    	lea    -0x124(%ebp),%edx
c0100a9c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100a9f:	01 d0                	add    %edx,%eax
c0100aa1:	c6 00 00             	movb   $0x0,(%eax)
                fnname, eip - info.eip_fn_addr);
c0100aa4:	8b 45 ec             	mov    -0x14(%ebp),%eax
        cprintf("    %s:%d: %s+%d\n", info.eip_file, info.eip_line,
c0100aa7:	8b 55 08             	mov    0x8(%ebp),%edx
c0100aaa:	89 d1                	mov    %edx,%ecx
c0100aac:	29 c1                	sub    %eax,%ecx
c0100aae:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0100ab1:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0100ab4:	89 4c 24 10          	mov    %ecx,0x10(%esp)
c0100ab8:	8d 8d dc fe ff ff    	lea    -0x124(%ebp),%ecx
c0100abe:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c0100ac2:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100ac6:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100aca:	c7 04 24 c2 91 10 c0 	movl   $0xc01091c2,(%esp)
c0100ad1:	e8 03 f8 ff ff       	call   c01002d9 <cprintf>
}
c0100ad6:	90                   	nop
c0100ad7:	c9                   	leave  
c0100ad8:	c3                   	ret    

c0100ad9 <read_eip>:

static __noinline uint32_t
read_eip(void) {
c0100ad9:	f3 0f 1e fb          	endbr32 
c0100add:	55                   	push   %ebp
c0100ade:	89 e5                	mov    %esp,%ebp
c0100ae0:	83 ec 10             	sub    $0x10,%esp
    uint32_t eip;
    asm volatile("movl 4(%%ebp), %0" : "=r" (eip));
c0100ae3:	8b 45 04             	mov    0x4(%ebp),%eax
c0100ae6:	89 45 fc             	mov    %eax,-0x4(%ebp)
    return eip;
c0100ae9:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0100aec:	c9                   	leave  
c0100aed:	c3                   	ret    

c0100aee <print_stackframe>:
 *
 * Note that, the length of ebp-chain is limited. In boot/bootasm.S, before jumping
 * to the kernel entry, the value of ebp has been set to zero, that's the boundary.
 * */
void
print_stackframe(void) {
c0100aee:	f3 0f 1e fb          	endbr32 
c0100af2:	55                   	push   %ebp
c0100af3:	89 e5                	mov    %esp,%ebp
      *    (3.4) call print_debuginfo(eip-1) to print the C calling function name and line number, etc.
      *    (3.5) popup a calling stackframe
      *           NOTICE: the calling funciton's return addr eip  = ss:[ebp+4]
      *                   the calling funciton's ebp = ss:[ebp]
      */
}
c0100af5:	90                   	nop
c0100af6:	5d                   	pop    %ebp
c0100af7:	c3                   	ret    

c0100af8 <parse>:
#define MAXARGS         16
#define WHITESPACE      " \t\n\r"

/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
c0100af8:	f3 0f 1e fb          	endbr32 
c0100afc:	55                   	push   %ebp
c0100afd:	89 e5                	mov    %esp,%ebp
c0100aff:	83 ec 28             	sub    $0x28,%esp
    int argc = 0;
c0100b02:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    while (1) {
        // find global whitespace
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c0100b09:	eb 0c                	jmp    c0100b17 <parse+0x1f>
            *buf ++ = '\0';
c0100b0b:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b0e:	8d 50 01             	lea    0x1(%eax),%edx
c0100b11:	89 55 08             	mov    %edx,0x8(%ebp)
c0100b14:	c6 00 00             	movb   $0x0,(%eax)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c0100b17:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b1a:	0f b6 00             	movzbl (%eax),%eax
c0100b1d:	84 c0                	test   %al,%al
c0100b1f:	74 1d                	je     c0100b3e <parse+0x46>
c0100b21:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b24:	0f b6 00             	movzbl (%eax),%eax
c0100b27:	0f be c0             	movsbl %al,%eax
c0100b2a:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100b2e:	c7 04 24 54 92 10 c0 	movl   $0xc0109254,(%esp)
c0100b35:	e8 f1 79 00 00       	call   c010852b <strchr>
c0100b3a:	85 c0                	test   %eax,%eax
c0100b3c:	75 cd                	jne    c0100b0b <parse+0x13>
        }
        if (*buf == '\0') {
c0100b3e:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b41:	0f b6 00             	movzbl (%eax),%eax
c0100b44:	84 c0                	test   %al,%al
c0100b46:	74 65                	je     c0100bad <parse+0xb5>
            break;
        }

        // save and scan past next arg
        if (argc == MAXARGS - 1) {
c0100b48:	83 7d f4 0f          	cmpl   $0xf,-0xc(%ebp)
c0100b4c:	75 14                	jne    c0100b62 <parse+0x6a>
            cprintf("Too many arguments (max %d).\n", MAXARGS);
c0100b4e:	c7 44 24 04 10 00 00 	movl   $0x10,0x4(%esp)
c0100b55:	00 
c0100b56:	c7 04 24 59 92 10 c0 	movl   $0xc0109259,(%esp)
c0100b5d:	e8 77 f7 ff ff       	call   c01002d9 <cprintf>
        }
        argv[argc ++] = buf;
c0100b62:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100b65:	8d 50 01             	lea    0x1(%eax),%edx
c0100b68:	89 55 f4             	mov    %edx,-0xc(%ebp)
c0100b6b:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0100b72:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100b75:	01 c2                	add    %eax,%edx
c0100b77:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b7a:	89 02                	mov    %eax,(%edx)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
c0100b7c:	eb 03                	jmp    c0100b81 <parse+0x89>
            buf ++;
c0100b7e:	ff 45 08             	incl   0x8(%ebp)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
c0100b81:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b84:	0f b6 00             	movzbl (%eax),%eax
c0100b87:	84 c0                	test   %al,%al
c0100b89:	74 8c                	je     c0100b17 <parse+0x1f>
c0100b8b:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b8e:	0f b6 00             	movzbl (%eax),%eax
c0100b91:	0f be c0             	movsbl %al,%eax
c0100b94:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100b98:	c7 04 24 54 92 10 c0 	movl   $0xc0109254,(%esp)
c0100b9f:	e8 87 79 00 00       	call   c010852b <strchr>
c0100ba4:	85 c0                	test   %eax,%eax
c0100ba6:	74 d6                	je     c0100b7e <parse+0x86>
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c0100ba8:	e9 6a ff ff ff       	jmp    c0100b17 <parse+0x1f>
            break;
c0100bad:	90                   	nop
        }
    }
    return argc;
c0100bae:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0100bb1:	c9                   	leave  
c0100bb2:	c3                   	ret    

c0100bb3 <runcmd>:
/* *
 * runcmd - parse the input string, split it into separated arguments
 * and then lookup and invoke some related commands/
 * */
static int
runcmd(char *buf, struct trapframe *tf) {
c0100bb3:	f3 0f 1e fb          	endbr32 
c0100bb7:	55                   	push   %ebp
c0100bb8:	89 e5                	mov    %esp,%ebp
c0100bba:	53                   	push   %ebx
c0100bbb:	83 ec 64             	sub    $0x64,%esp
    char *argv[MAXARGS];
    int argc = parse(buf, argv);
c0100bbe:	8d 45 b0             	lea    -0x50(%ebp),%eax
c0100bc1:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100bc5:	8b 45 08             	mov    0x8(%ebp),%eax
c0100bc8:	89 04 24             	mov    %eax,(%esp)
c0100bcb:	e8 28 ff ff ff       	call   c0100af8 <parse>
c0100bd0:	89 45 f0             	mov    %eax,-0x10(%ebp)
    if (argc == 0) {
c0100bd3:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0100bd7:	75 0a                	jne    c0100be3 <runcmd+0x30>
        return 0;
c0100bd9:	b8 00 00 00 00       	mov    $0x0,%eax
c0100bde:	e9 83 00 00 00       	jmp    c0100c66 <runcmd+0xb3>
    }
    int i;
    for (i = 0; i < NCOMMANDS; i ++) {
c0100be3:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0100bea:	eb 5a                	jmp    c0100c46 <runcmd+0x93>
        if (strcmp(commands[i].name, argv[0]) == 0) {
c0100bec:	8b 4d b0             	mov    -0x50(%ebp),%ecx
c0100bef:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0100bf2:	89 d0                	mov    %edx,%eax
c0100bf4:	01 c0                	add    %eax,%eax
c0100bf6:	01 d0                	add    %edx,%eax
c0100bf8:	c1 e0 02             	shl    $0x2,%eax
c0100bfb:	05 00 30 12 c0       	add    $0xc0123000,%eax
c0100c00:	8b 00                	mov    (%eax),%eax
c0100c02:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c0100c06:	89 04 24             	mov    %eax,(%esp)
c0100c09:	e8 79 78 00 00       	call   c0108487 <strcmp>
c0100c0e:	85 c0                	test   %eax,%eax
c0100c10:	75 31                	jne    c0100c43 <runcmd+0x90>
            return commands[i].func(argc - 1, argv + 1, tf);
c0100c12:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0100c15:	89 d0                	mov    %edx,%eax
c0100c17:	01 c0                	add    %eax,%eax
c0100c19:	01 d0                	add    %edx,%eax
c0100c1b:	c1 e0 02             	shl    $0x2,%eax
c0100c1e:	05 08 30 12 c0       	add    $0xc0123008,%eax
c0100c23:	8b 10                	mov    (%eax),%edx
c0100c25:	8d 45 b0             	lea    -0x50(%ebp),%eax
c0100c28:	83 c0 04             	add    $0x4,%eax
c0100c2b:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c0100c2e:	8d 59 ff             	lea    -0x1(%ecx),%ebx
c0100c31:	8b 4d 0c             	mov    0xc(%ebp),%ecx
c0100c34:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0100c38:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100c3c:	89 1c 24             	mov    %ebx,(%esp)
c0100c3f:	ff d2                	call   *%edx
c0100c41:	eb 23                	jmp    c0100c66 <runcmd+0xb3>
    for (i = 0; i < NCOMMANDS; i ++) {
c0100c43:	ff 45 f4             	incl   -0xc(%ebp)
c0100c46:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100c49:	83 f8 02             	cmp    $0x2,%eax
c0100c4c:	76 9e                	jbe    c0100bec <runcmd+0x39>
        }
    }
    cprintf("Unknown command '%s'\n", argv[0]);
c0100c4e:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0100c51:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100c55:	c7 04 24 77 92 10 c0 	movl   $0xc0109277,(%esp)
c0100c5c:	e8 78 f6 ff ff       	call   c01002d9 <cprintf>
    return 0;
c0100c61:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100c66:	83 c4 64             	add    $0x64,%esp
c0100c69:	5b                   	pop    %ebx
c0100c6a:	5d                   	pop    %ebp
c0100c6b:	c3                   	ret    

c0100c6c <kmonitor>:

/***** Implementations of basic kernel monitor commands *****/

void
kmonitor(struct trapframe *tf) {
c0100c6c:	f3 0f 1e fb          	endbr32 
c0100c70:	55                   	push   %ebp
c0100c71:	89 e5                	mov    %esp,%ebp
c0100c73:	83 ec 28             	sub    $0x28,%esp
    cprintf("Welcome to the kernel debug monitor!!\n");
c0100c76:	c7 04 24 90 92 10 c0 	movl   $0xc0109290,(%esp)
c0100c7d:	e8 57 f6 ff ff       	call   c01002d9 <cprintf>
    cprintf("Type 'help' for a list of commands.\n");
c0100c82:	c7 04 24 b8 92 10 c0 	movl   $0xc01092b8,(%esp)
c0100c89:	e8 4b f6 ff ff       	call   c01002d9 <cprintf>

    if (tf != NULL) {
c0100c8e:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0100c92:	74 0b                	je     c0100c9f <kmonitor+0x33>
        print_trapframe(tf);
c0100c94:	8b 45 08             	mov    0x8(%ebp),%eax
c0100c97:	89 04 24             	mov    %eax,(%esp)
c0100c9a:	e8 a9 16 00 00       	call   c0102348 <print_trapframe>
    }

    char *buf;
    while (1) {
        if ((buf = readline("K> ")) != NULL) {
c0100c9f:	c7 04 24 dd 92 10 c0 	movl   $0xc01092dd,(%esp)
c0100ca6:	e8 e1 f6 ff ff       	call   c010038c <readline>
c0100cab:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0100cae:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0100cb2:	74 eb                	je     c0100c9f <kmonitor+0x33>
            if (runcmd(buf, tf) < 0) {
c0100cb4:	8b 45 08             	mov    0x8(%ebp),%eax
c0100cb7:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100cbb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100cbe:	89 04 24             	mov    %eax,(%esp)
c0100cc1:	e8 ed fe ff ff       	call   c0100bb3 <runcmd>
c0100cc6:	85 c0                	test   %eax,%eax
c0100cc8:	78 02                	js     c0100ccc <kmonitor+0x60>
        if ((buf = readline("K> ")) != NULL) {
c0100cca:	eb d3                	jmp    c0100c9f <kmonitor+0x33>
                break;
c0100ccc:	90                   	nop
            }
        }
    }
}
c0100ccd:	90                   	nop
c0100cce:	c9                   	leave  
c0100ccf:	c3                   	ret    

c0100cd0 <mon_help>:

/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
c0100cd0:	f3 0f 1e fb          	endbr32 
c0100cd4:	55                   	push   %ebp
c0100cd5:	89 e5                	mov    %esp,%ebp
c0100cd7:	83 ec 28             	sub    $0x28,%esp
    int i;
    for (i = 0; i < NCOMMANDS; i ++) {
c0100cda:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0100ce1:	eb 3d                	jmp    c0100d20 <mon_help+0x50>
        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
c0100ce3:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0100ce6:	89 d0                	mov    %edx,%eax
c0100ce8:	01 c0                	add    %eax,%eax
c0100cea:	01 d0                	add    %edx,%eax
c0100cec:	c1 e0 02             	shl    $0x2,%eax
c0100cef:	05 04 30 12 c0       	add    $0xc0123004,%eax
c0100cf4:	8b 08                	mov    (%eax),%ecx
c0100cf6:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0100cf9:	89 d0                	mov    %edx,%eax
c0100cfb:	01 c0                	add    %eax,%eax
c0100cfd:	01 d0                	add    %edx,%eax
c0100cff:	c1 e0 02             	shl    $0x2,%eax
c0100d02:	05 00 30 12 c0       	add    $0xc0123000,%eax
c0100d07:	8b 00                	mov    (%eax),%eax
c0100d09:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0100d0d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100d11:	c7 04 24 e1 92 10 c0 	movl   $0xc01092e1,(%esp)
c0100d18:	e8 bc f5 ff ff       	call   c01002d9 <cprintf>
    for (i = 0; i < NCOMMANDS; i ++) {
c0100d1d:	ff 45 f4             	incl   -0xc(%ebp)
c0100d20:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100d23:	83 f8 02             	cmp    $0x2,%eax
c0100d26:	76 bb                	jbe    c0100ce3 <mon_help+0x13>
    }
    return 0;
c0100d28:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100d2d:	c9                   	leave  
c0100d2e:	c3                   	ret    

c0100d2f <mon_kerninfo>:
/* *
 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 * print the memory occupancy in kernel.
 * */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
c0100d2f:	f3 0f 1e fb          	endbr32 
c0100d33:	55                   	push   %ebp
c0100d34:	89 e5                	mov    %esp,%ebp
c0100d36:	83 ec 08             	sub    $0x8,%esp
    print_kerninfo();
c0100d39:	e8 5e fc ff ff       	call   c010099c <print_kerninfo>
    return 0;
c0100d3e:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100d43:	c9                   	leave  
c0100d44:	c3                   	ret    

c0100d45 <mon_backtrace>:
/* *
 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 * print a backtrace of the stack.
 * */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
c0100d45:	f3 0f 1e fb          	endbr32 
c0100d49:	55                   	push   %ebp
c0100d4a:	89 e5                	mov    %esp,%ebp
c0100d4c:	83 ec 08             	sub    $0x8,%esp
    print_stackframe();
c0100d4f:	e8 9a fd ff ff       	call   c0100aee <print_stackframe>
    return 0;
c0100d54:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100d59:	c9                   	leave  
c0100d5a:	c3                   	ret    

c0100d5b <ide_wait_ready>:
 *                    函数会在设备忙状态解除后检查错误位如果设置为false，
 *                    函数不会进行错误检查
 * @return 返回0表示设备成功进入就绪状态，-1表示设备在操作中检测到了错误
 */
static int
ide_wait_ready(unsigned short iobase, bool check_error) {
c0100d5b:	f3 0f 1e fb          	endbr32 
c0100d5f:	55                   	push   %ebp
c0100d60:	89 e5                	mov    %esp,%ebp
c0100d62:	83 ec 14             	sub    $0x14,%esp
c0100d65:	8b 45 08             	mov    0x8(%ebp),%eax
c0100d68:	66 89 45 ec          	mov    %ax,-0x14(%ebp)
    int r;
    // 循环检查IDE设备的状态寄存器，直到忙状态位清除
    while ((r = inb(iobase + ISA_STATUS)) & IDE_BSY)
c0100d6c:	90                   	nop
c0100d6d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100d70:	83 c0 07             	add    $0x7,%eax
c0100d73:	0f b7 c0             	movzwl %ax,%eax
c0100d76:	66 89 45 fa          	mov    %ax,-0x6(%ebp)
static inline void invlpg(void *addr) __attribute__((always_inline));

static inline uint8_t
inb(uint16_t port) {
    uint8_t data;
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100d7a:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c0100d7e:	89 c2                	mov    %eax,%edx
c0100d80:	ec                   	in     (%dx),%al
c0100d81:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c0100d84:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c0100d88:	0f b6 c0             	movzbl %al,%eax
c0100d8b:	89 45 fc             	mov    %eax,-0x4(%ebp)
c0100d8e:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100d91:	25 80 00 00 00       	and    $0x80,%eax
c0100d96:	85 c0                	test   %eax,%eax
c0100d98:	75 d3                	jne    c0100d6d <ide_wait_ready+0x12>
        /* nothing */;
    // 如果需要检查错误，并且状态寄存器中的错误位被设置，则返回错误
    if (check_error && (r & (IDE_DF | IDE_ERR)) != 0) {
c0100d9a:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0100d9e:	74 11                	je     c0100db1 <ide_wait_ready+0x56>
c0100da0:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100da3:	83 e0 21             	and    $0x21,%eax
c0100da6:	85 c0                	test   %eax,%eax
c0100da8:	74 07                	je     c0100db1 <ide_wait_ready+0x56>
        return -1;
c0100daa:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c0100daf:	eb 05                	jmp    c0100db6 <ide_wait_ready+0x5b>
    }
    // 设备就绪，无错误，返回0
    return 0;
c0100db1:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100db6:	c9                   	leave  
c0100db7:	c3                   	ret    

c0100db8 <ide_init>:
 * 初始化IDE设备。
 *
 * 此函数初始化所有IDE设备，设置设备状态，读取设备信息，并启用IDE设备中断。
 */
void
ide_init(void) {
c0100db8:	f3 0f 1e fb          	endbr32 
c0100dbc:	55                   	push   %ebp
c0100dbd:	89 e5                	mov    %esp,%ebp
c0100dbf:	57                   	push   %edi
c0100dc0:	53                   	push   %ebx
c0100dc1:	81 ec 50 02 00 00    	sub    $0x250,%esp
    // 确保扇区大小是4的倍数，以满足后续数据访问的对齐要求
    static_assert((SECTSIZE % 4) == 0);
    unsigned short ideno, iobase;
    for (ideno = 0; ideno < MAX_IDE; ideno ++) {
c0100dc7:	66 c7 45 f6 00 00    	movw   $0x0,-0xa(%ebp)
c0100dcd:	e9 bd 02 00 00       	jmp    c010108f <ide_init+0x2d7>
        // 假设此处没有设备
        /* assume that no device here */
        ide_devices[ideno].valid = 0;
c0100dd2:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0100dd6:	89 d0                	mov    %edx,%eax
c0100dd8:	c1 e0 03             	shl    $0x3,%eax
c0100ddb:	29 d0                	sub    %edx,%eax
c0100ddd:	c1 e0 03             	shl    $0x3,%eax
c0100de0:	05 40 64 12 c0       	add    $0xc0126440,%eax
c0100de5:	c6 00 00             	movb   $0x0,(%eax)

        iobase = IO_BASE(ideno);
c0100de8:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0100dec:	d1 e8                	shr    %eax
c0100dee:	0f b7 c0             	movzwl %ax,%eax
c0100df1:	8b 04 85 ec 92 10 c0 	mov    -0x3fef6d14(,%eax,4),%eax
c0100df8:	66 89 45 ea          	mov    %ax,-0x16(%ebp)

        /* wait device ready */
        // 等待设备准备好
        ide_wait_ready(iobase, 0);
c0100dfc:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100e00:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0100e07:	00 
c0100e08:	89 04 24             	mov    %eax,(%esp)
c0100e0b:	e8 4b ff ff ff       	call   c0100d5b <ide_wait_ready>

        /* step1: select drive */
        // 第一步：选择驱动器
        outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4));
c0100e10:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0100e14:	c1 e0 04             	shl    $0x4,%eax
c0100e17:	24 10                	and    $0x10,%al
c0100e19:	0c e0                	or     $0xe0,%al
c0100e1b:	0f b6 c0             	movzbl %al,%eax
c0100e1e:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0100e22:	83 c2 06             	add    $0x6,%edx
c0100e25:	0f b7 d2             	movzwl %dx,%edx
c0100e28:	66 89 55 ca          	mov    %dx,-0x36(%ebp)
c0100e2c:	88 45 c9             	mov    %al,-0x37(%ebp)
        : "memory", "cc");
}

static inline void
outb(uint16_t port, uint8_t data) {
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100e2f:	0f b6 45 c9          	movzbl -0x37(%ebp),%eax
c0100e33:	0f b7 55 ca          	movzwl -0x36(%ebp),%edx
c0100e37:	ee                   	out    %al,(%dx)
}
c0100e38:	90                   	nop
        ide_wait_ready(iobase, 0);
c0100e39:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100e3d:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0100e44:	00 
c0100e45:	89 04 24             	mov    %eax,(%esp)
c0100e48:	e8 0e ff ff ff       	call   c0100d5b <ide_wait_ready>

        /* step2: send ATA identify command */
        // 第二步：发送ATA识别命令
        outb(iobase + ISA_COMMAND, IDE_CMD_IDENTIFY);
c0100e4d:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100e51:	83 c0 07             	add    $0x7,%eax
c0100e54:	0f b7 c0             	movzwl %ax,%eax
c0100e57:	66 89 45 ce          	mov    %ax,-0x32(%ebp)
c0100e5b:	c6 45 cd ec          	movb   $0xec,-0x33(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100e5f:	0f b6 45 cd          	movzbl -0x33(%ebp),%eax
c0100e63:	0f b7 55 ce          	movzwl -0x32(%ebp),%edx
c0100e67:	ee                   	out    %al,(%dx)
}
c0100e68:	90                   	nop
        ide_wait_ready(iobase, 0);
c0100e69:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100e6d:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0100e74:	00 
c0100e75:	89 04 24             	mov    %eax,(%esp)
c0100e78:	e8 de fe ff ff       	call   c0100d5b <ide_wait_ready>

        /* step3: polling */
        // 第三步：轮询
        if (inb(iobase + ISA_STATUS) == 0 || ide_wait_ready(iobase, 1) != 0) {
c0100e7d:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100e81:	83 c0 07             	add    $0x7,%eax
c0100e84:	0f b7 c0             	movzwl %ax,%eax
c0100e87:	66 89 45 d2          	mov    %ax,-0x2e(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100e8b:	0f b7 45 d2          	movzwl -0x2e(%ebp),%eax
c0100e8f:	89 c2                	mov    %eax,%edx
c0100e91:	ec                   	in     (%dx),%al
c0100e92:	88 45 d1             	mov    %al,-0x2f(%ebp)
    return data;
c0100e95:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c0100e99:	84 c0                	test   %al,%al
c0100e9b:	0f 84 e4 01 00 00    	je     c0101085 <ide_init+0x2cd>
c0100ea1:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100ea5:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0100eac:	00 
c0100ead:	89 04 24             	mov    %eax,(%esp)
c0100eb0:	e8 a6 fe ff ff       	call   c0100d5b <ide_wait_ready>
c0100eb5:	85 c0                	test   %eax,%eax
c0100eb7:	0f 85 c8 01 00 00    	jne    c0101085 <ide_init+0x2cd>
            continue ;
        }
         // 设备正常
        /* device is ok */
        ide_devices[ideno].valid = 1;
c0100ebd:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0100ec1:	89 d0                	mov    %edx,%eax
c0100ec3:	c1 e0 03             	shl    $0x3,%eax
c0100ec6:	29 d0                	sub    %edx,%eax
c0100ec8:	c1 e0 03             	shl    $0x3,%eax
c0100ecb:	05 40 64 12 c0       	add    $0xc0126440,%eax
c0100ed0:	c6 00 01             	movb   $0x1,(%eax)

        // 读取设备的识别空间
        /* read identification space of the device */
        unsigned int buffer[128];
        insl(iobase + ISA_DATA, buffer, sizeof(buffer) / sizeof(unsigned int));
c0100ed3:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100ed7:	89 45 c4             	mov    %eax,-0x3c(%ebp)
c0100eda:	8d 85 bc fd ff ff    	lea    -0x244(%ebp),%eax
c0100ee0:	89 45 c0             	mov    %eax,-0x40(%ebp)
c0100ee3:	c7 45 bc 80 00 00 00 	movl   $0x80,-0x44(%ebp)
    asm volatile (
c0100eea:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c0100eed:	8b 4d c0             	mov    -0x40(%ebp),%ecx
c0100ef0:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0100ef3:	89 cb                	mov    %ecx,%ebx
c0100ef5:	89 df                	mov    %ebx,%edi
c0100ef7:	89 c1                	mov    %eax,%ecx
c0100ef9:	fc                   	cld    
c0100efa:	f2 6d                	repnz insl (%dx),%es:(%edi)
c0100efc:	89 c8                	mov    %ecx,%eax
c0100efe:	89 fb                	mov    %edi,%ebx
c0100f00:	89 5d c0             	mov    %ebx,-0x40(%ebp)
c0100f03:	89 45 bc             	mov    %eax,-0x44(%ebp)
}
c0100f06:	90                   	nop

        unsigned char *ident = (unsigned char *)buffer;
c0100f07:	8d 85 bc fd ff ff    	lea    -0x244(%ebp),%eax
c0100f0d:	89 45 e4             	mov    %eax,-0x1c(%ebp)
        unsigned int sectors;
        unsigned int cmdsets = *(unsigned int *)(ident + IDE_IDENT_CMDSETS);
c0100f10:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100f13:	8b 80 a4 00 00 00    	mov    0xa4(%eax),%eax
c0100f19:	89 45 e0             	mov    %eax,-0x20(%ebp)
        // 判断设备使用48位还是28位寻址
        /* device use 48-bits or 28-bits addressing */
        if (cmdsets & (1 << 26)) {
c0100f1c:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0100f1f:	25 00 00 00 04       	and    $0x4000000,%eax
c0100f24:	85 c0                	test   %eax,%eax
c0100f26:	74 0e                	je     c0100f36 <ide_init+0x17e>
            sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA_EXT);
c0100f28:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100f2b:	8b 80 c8 00 00 00    	mov    0xc8(%eax),%eax
c0100f31:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0100f34:	eb 09                	jmp    c0100f3f <ide_init+0x187>
        }
        else {
            sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA);
c0100f36:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100f39:	8b 40 78             	mov    0x78(%eax),%eax
c0100f3c:	89 45 f0             	mov    %eax,-0x10(%ebp)
        }
        ide_devices[ideno].sets = cmdsets;
c0100f3f:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0100f43:	89 d0                	mov    %edx,%eax
c0100f45:	c1 e0 03             	shl    $0x3,%eax
c0100f48:	29 d0                	sub    %edx,%eax
c0100f4a:	c1 e0 03             	shl    $0x3,%eax
c0100f4d:	8d 90 44 64 12 c0    	lea    -0x3fed9bbc(%eax),%edx
c0100f53:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0100f56:	89 02                	mov    %eax,(%edx)
        ide_devices[ideno].size = sectors;
c0100f58:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0100f5c:	89 d0                	mov    %edx,%eax
c0100f5e:	c1 e0 03             	shl    $0x3,%eax
c0100f61:	29 d0                	sub    %edx,%eax
c0100f63:	c1 e0 03             	shl    $0x3,%eax
c0100f66:	8d 90 48 64 12 c0    	lea    -0x3fed9bb8(%eax),%edx
c0100f6c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100f6f:	89 02                	mov    %eax,(%edx)

        /* check if supports LBA */
        // 检查是否支持LBA
        assert((*(unsigned short *)(ident + IDE_IDENT_CAPABILITIES) & 0x200) != 0);
c0100f71:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100f74:	83 c0 62             	add    $0x62,%eax
c0100f77:	0f b7 00             	movzwl (%eax),%eax
c0100f7a:	25 00 02 00 00       	and    $0x200,%eax
c0100f7f:	85 c0                	test   %eax,%eax
c0100f81:	75 24                	jne    c0100fa7 <ide_init+0x1ef>
c0100f83:	c7 44 24 0c f4 92 10 	movl   $0xc01092f4,0xc(%esp)
c0100f8a:	c0 
c0100f8b:	c7 44 24 08 37 93 10 	movl   $0xc0109337,0x8(%esp)
c0100f92:	c0 
c0100f93:	c7 44 24 04 9a 00 00 	movl   $0x9a,0x4(%esp)
c0100f9a:	00 
c0100f9b:	c7 04 24 4c 93 10 c0 	movl   $0xc010934c,(%esp)
c0100fa2:	e8 9e f4 ff ff       	call   c0100445 <__panic>

        unsigned char *model = ide_devices[ideno].model, *data = ident + IDE_IDENT_MODEL;
c0100fa7:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0100fab:	89 d0                	mov    %edx,%eax
c0100fad:	c1 e0 03             	shl    $0x3,%eax
c0100fb0:	29 d0                	sub    %edx,%eax
c0100fb2:	c1 e0 03             	shl    $0x3,%eax
c0100fb5:	05 40 64 12 c0       	add    $0xc0126440,%eax
c0100fba:	83 c0 0c             	add    $0xc,%eax
c0100fbd:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0100fc0:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100fc3:	83 c0 36             	add    $0x36,%eax
c0100fc6:	89 45 d8             	mov    %eax,-0x28(%ebp)
        unsigned int i, length = 40;
c0100fc9:	c7 45 d4 28 00 00 00 	movl   $0x28,-0x2c(%ebp)
        for (i = 0; i < length; i += 2) {
c0100fd0:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0100fd7:	eb 34                	jmp    c010100d <ide_init+0x255>
            model[i] = data[i + 1], model[i + 1] = data[i];
c0100fd9:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100fdc:	8d 50 01             	lea    0x1(%eax),%edx
c0100fdf:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0100fe2:	01 c2                	add    %eax,%edx
c0100fe4:	8b 4d dc             	mov    -0x24(%ebp),%ecx
c0100fe7:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100fea:	01 c8                	add    %ecx,%eax
c0100fec:	0f b6 12             	movzbl (%edx),%edx
c0100fef:	88 10                	mov    %dl,(%eax)
c0100ff1:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0100ff4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100ff7:	01 c2                	add    %eax,%edx
c0100ff9:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100ffc:	8d 48 01             	lea    0x1(%eax),%ecx
c0100fff:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0101002:	01 c8                	add    %ecx,%eax
c0101004:	0f b6 12             	movzbl (%edx),%edx
c0101007:	88 10                	mov    %dl,(%eax)
        for (i = 0; i < length; i += 2) {
c0101009:	83 45 ec 02          	addl   $0x2,-0x14(%ebp)
c010100d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101010:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c0101013:	72 c4                	jb     c0100fd9 <ide_init+0x221>
        }
        do {
            model[i] = '\0';
c0101015:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0101018:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010101b:	01 d0                	add    %edx,%eax
c010101d:	c6 00 00             	movb   $0x0,(%eax)
        } while (i -- > 0 && model[i] == ' ');
c0101020:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101023:	8d 50 ff             	lea    -0x1(%eax),%edx
c0101026:	89 55 ec             	mov    %edx,-0x14(%ebp)
c0101029:	85 c0                	test   %eax,%eax
c010102b:	74 0f                	je     c010103c <ide_init+0x284>
c010102d:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0101030:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101033:	01 d0                	add    %edx,%eax
c0101035:	0f b6 00             	movzbl (%eax),%eax
c0101038:	3c 20                	cmp    $0x20,%al
c010103a:	74 d9                	je     c0101015 <ide_init+0x25d>

        cprintf("ide %d: %10u(sectors), '%s'.\n", ideno, ide_devices[ideno].size, ide_devices[ideno].model);
c010103c:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101040:	89 d0                	mov    %edx,%eax
c0101042:	c1 e0 03             	shl    $0x3,%eax
c0101045:	29 d0                	sub    %edx,%eax
c0101047:	c1 e0 03             	shl    $0x3,%eax
c010104a:	05 40 64 12 c0       	add    $0xc0126440,%eax
c010104f:	8d 48 0c             	lea    0xc(%eax),%ecx
c0101052:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101056:	89 d0                	mov    %edx,%eax
c0101058:	c1 e0 03             	shl    $0x3,%eax
c010105b:	29 d0                	sub    %edx,%eax
c010105d:	c1 e0 03             	shl    $0x3,%eax
c0101060:	05 48 64 12 c0       	add    $0xc0126448,%eax
c0101065:	8b 10                	mov    (%eax),%edx
c0101067:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010106b:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c010106f:	89 54 24 08          	mov    %edx,0x8(%esp)
c0101073:	89 44 24 04          	mov    %eax,0x4(%esp)
c0101077:	c7 04 24 5e 93 10 c0 	movl   $0xc010935e,(%esp)
c010107e:	e8 56 f2 ff ff       	call   c01002d9 <cprintf>
c0101083:	eb 01                	jmp    c0101086 <ide_init+0x2ce>
            continue ;
c0101085:	90                   	nop
    for (ideno = 0; ideno < MAX_IDE; ideno ++) {
c0101086:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010108a:	40                   	inc    %eax
c010108b:	66 89 45 f6          	mov    %ax,-0xa(%ebp)
c010108f:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101093:	83 f8 03             	cmp    $0x3,%eax
c0101096:	0f 86 36 fd ff ff    	jbe    c0100dd2 <ide_init+0x1a>
    }

    // enable ide interrupt
    // 启用IDE中断
    pic_enable(IRQ_IDE1);
c010109c:	c7 04 24 0e 00 00 00 	movl   $0xe,(%esp)
c01010a3:	e8 1f 0f 00 00       	call   c0101fc7 <pic_enable>
    pic_enable(IRQ_IDE2);
c01010a8:	c7 04 24 0f 00 00 00 	movl   $0xf,(%esp)
c01010af:	e8 13 0f 00 00       	call   c0101fc7 <pic_enable>
}
c01010b4:	90                   	nop
c01010b5:	81 c4 50 02 00 00    	add    $0x250,%esp
c01010bb:	5b                   	pop    %ebx
c01010bc:	5f                   	pop    %edi
c01010bd:	5d                   	pop    %ebp
c01010be:	c3                   	ret    

c01010bf <ide_device_valid>:

bool
ide_device_valid(unsigned short ideno) {
c01010bf:	f3 0f 1e fb          	endbr32 
c01010c3:	55                   	push   %ebp
c01010c4:	89 e5                	mov    %esp,%ebp
c01010c6:	83 ec 04             	sub    $0x4,%esp
c01010c9:	8b 45 08             	mov    0x8(%ebp),%eax
c01010cc:	66 89 45 fc          	mov    %ax,-0x4(%ebp)
    return VALID_IDE(ideno);
c01010d0:	0f b7 45 fc          	movzwl -0x4(%ebp),%eax
c01010d4:	83 f8 03             	cmp    $0x3,%eax
c01010d7:	77 21                	ja     c01010fa <ide_device_valid+0x3b>
c01010d9:	0f b7 55 fc          	movzwl -0x4(%ebp),%edx
c01010dd:	89 d0                	mov    %edx,%eax
c01010df:	c1 e0 03             	shl    $0x3,%eax
c01010e2:	29 d0                	sub    %edx,%eax
c01010e4:	c1 e0 03             	shl    $0x3,%eax
c01010e7:	05 40 64 12 c0       	add    $0xc0126440,%eax
c01010ec:	0f b6 00             	movzbl (%eax),%eax
c01010ef:	84 c0                	test   %al,%al
c01010f1:	74 07                	je     c01010fa <ide_device_valid+0x3b>
c01010f3:	b8 01 00 00 00       	mov    $0x1,%eax
c01010f8:	eb 05                	jmp    c01010ff <ide_device_valid+0x40>
c01010fa:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01010ff:	c9                   	leave  
c0101100:	c3                   	ret    

c0101101 <ide_device_size>:

size_t
ide_device_size(unsigned short ideno) {
c0101101:	f3 0f 1e fb          	endbr32 
c0101105:	55                   	push   %ebp
c0101106:	89 e5                	mov    %esp,%ebp
c0101108:	83 ec 08             	sub    $0x8,%esp
c010110b:	8b 45 08             	mov    0x8(%ebp),%eax
c010110e:	66 89 45 fc          	mov    %ax,-0x4(%ebp)
    if (ide_device_valid(ideno)) {
c0101112:	0f b7 45 fc          	movzwl -0x4(%ebp),%eax
c0101116:	89 04 24             	mov    %eax,(%esp)
c0101119:	e8 a1 ff ff ff       	call   c01010bf <ide_device_valid>
c010111e:	85 c0                	test   %eax,%eax
c0101120:	74 17                	je     c0101139 <ide_device_size+0x38>
        return ide_devices[ideno].size;
c0101122:	0f b7 55 fc          	movzwl -0x4(%ebp),%edx
c0101126:	89 d0                	mov    %edx,%eax
c0101128:	c1 e0 03             	shl    $0x3,%eax
c010112b:	29 d0                	sub    %edx,%eax
c010112d:	c1 e0 03             	shl    $0x3,%eax
c0101130:	05 48 64 12 c0       	add    $0xc0126448,%eax
c0101135:	8b 00                	mov    (%eax),%eax
c0101137:	eb 05                	jmp    c010113e <ide_device_size+0x3d>
    }
    return 0;
c0101139:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010113e:	c9                   	leave  
c010113f:	c3                   	ret    

c0101140 <ide_read_secs>:

int
ide_read_secs(unsigned short ideno, uint32_t secno, void *dst, size_t nsecs) {
c0101140:	f3 0f 1e fb          	endbr32 
c0101144:	55                   	push   %ebp
c0101145:	89 e5                	mov    %esp,%ebp
c0101147:	57                   	push   %edi
c0101148:	53                   	push   %ebx
c0101149:	83 ec 50             	sub    $0x50,%esp
c010114c:	8b 45 08             	mov    0x8(%ebp),%eax
c010114f:	66 89 45 c4          	mov    %ax,-0x3c(%ebp)
    assert(nsecs <= MAX_NSECS && VALID_IDE(ideno));
c0101153:	81 7d 14 80 00 00 00 	cmpl   $0x80,0x14(%ebp)
c010115a:	77 23                	ja     c010117f <ide_read_secs+0x3f>
c010115c:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101160:	83 f8 03             	cmp    $0x3,%eax
c0101163:	77 1a                	ja     c010117f <ide_read_secs+0x3f>
c0101165:	0f b7 55 c4          	movzwl -0x3c(%ebp),%edx
c0101169:	89 d0                	mov    %edx,%eax
c010116b:	c1 e0 03             	shl    $0x3,%eax
c010116e:	29 d0                	sub    %edx,%eax
c0101170:	c1 e0 03             	shl    $0x3,%eax
c0101173:	05 40 64 12 c0       	add    $0xc0126440,%eax
c0101178:	0f b6 00             	movzbl (%eax),%eax
c010117b:	84 c0                	test   %al,%al
c010117d:	75 24                	jne    c01011a3 <ide_read_secs+0x63>
c010117f:	c7 44 24 0c 7c 93 10 	movl   $0xc010937c,0xc(%esp)
c0101186:	c0 
c0101187:	c7 44 24 08 37 93 10 	movl   $0xc0109337,0x8(%esp)
c010118e:	c0 
c010118f:	c7 44 24 04 bd 00 00 	movl   $0xbd,0x4(%esp)
c0101196:	00 
c0101197:	c7 04 24 4c 93 10 c0 	movl   $0xc010934c,(%esp)
c010119e:	e8 a2 f2 ff ff       	call   c0100445 <__panic>
    assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS);
c01011a3:	81 7d 0c ff ff ff 0f 	cmpl   $0xfffffff,0xc(%ebp)
c01011aa:	77 0f                	ja     c01011bb <ide_read_secs+0x7b>
c01011ac:	8b 55 0c             	mov    0xc(%ebp),%edx
c01011af:	8b 45 14             	mov    0x14(%ebp),%eax
c01011b2:	01 d0                	add    %edx,%eax
c01011b4:	3d 00 00 00 10       	cmp    $0x10000000,%eax
c01011b9:	76 24                	jbe    c01011df <ide_read_secs+0x9f>
c01011bb:	c7 44 24 0c a4 93 10 	movl   $0xc01093a4,0xc(%esp)
c01011c2:	c0 
c01011c3:	c7 44 24 08 37 93 10 	movl   $0xc0109337,0x8(%esp)
c01011ca:	c0 
c01011cb:	c7 44 24 04 be 00 00 	movl   $0xbe,0x4(%esp)
c01011d2:	00 
c01011d3:	c7 04 24 4c 93 10 c0 	movl   $0xc010934c,(%esp)
c01011da:	e8 66 f2 ff ff       	call   c0100445 <__panic>
    unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno);
c01011df:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c01011e3:	d1 e8                	shr    %eax
c01011e5:	0f b7 c0             	movzwl %ax,%eax
c01011e8:	8b 04 85 ec 92 10 c0 	mov    -0x3fef6d14(,%eax,4),%eax
c01011ef:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
c01011f3:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c01011f7:	d1 e8                	shr    %eax
c01011f9:	0f b7 c0             	movzwl %ax,%eax
c01011fc:	0f b7 04 85 ee 92 10 	movzwl -0x3fef6d12(,%eax,4),%eax
c0101203:	c0 
c0101204:	66 89 45 f0          	mov    %ax,-0x10(%ebp)

    ide_wait_ready(iobase, 0);
c0101208:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c010120c:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0101213:	00 
c0101214:	89 04 24             	mov    %eax,(%esp)
c0101217:	e8 3f fb ff ff       	call   c0100d5b <ide_wait_ready>

    // generate interrupt
    outb(ioctrl + ISA_CTRL, 0);
c010121c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010121f:	83 c0 02             	add    $0x2,%eax
c0101222:	0f b7 c0             	movzwl %ax,%eax
c0101225:	66 89 45 d6          	mov    %ax,-0x2a(%ebp)
c0101229:	c6 45 d5 00          	movb   $0x0,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010122d:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0101231:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0101235:	ee                   	out    %al,(%dx)
}
c0101236:	90                   	nop
    outb(iobase + ISA_SECCNT, nsecs);
c0101237:	8b 45 14             	mov    0x14(%ebp),%eax
c010123a:	0f b6 c0             	movzbl %al,%eax
c010123d:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101241:	83 c2 02             	add    $0x2,%edx
c0101244:	0f b7 d2             	movzwl %dx,%edx
c0101247:	66 89 55 da          	mov    %dx,-0x26(%ebp)
c010124b:	88 45 d9             	mov    %al,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010124e:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0101252:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c0101256:	ee                   	out    %al,(%dx)
}
c0101257:	90                   	nop
    outb(iobase + ISA_SECTOR, secno & 0xFF);
c0101258:	8b 45 0c             	mov    0xc(%ebp),%eax
c010125b:	0f b6 c0             	movzbl %al,%eax
c010125e:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101262:	83 c2 03             	add    $0x3,%edx
c0101265:	0f b7 d2             	movzwl %dx,%edx
c0101268:	66 89 55 de          	mov    %dx,-0x22(%ebp)
c010126c:	88 45 dd             	mov    %al,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010126f:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c0101273:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0101277:	ee                   	out    %al,(%dx)
}
c0101278:	90                   	nop
    outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF);
c0101279:	8b 45 0c             	mov    0xc(%ebp),%eax
c010127c:	c1 e8 08             	shr    $0x8,%eax
c010127f:	0f b6 c0             	movzbl %al,%eax
c0101282:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101286:	83 c2 04             	add    $0x4,%edx
c0101289:	0f b7 d2             	movzwl %dx,%edx
c010128c:	66 89 55 e2          	mov    %dx,-0x1e(%ebp)
c0101290:	88 45 e1             	mov    %al,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101293:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0101297:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c010129b:	ee                   	out    %al,(%dx)
}
c010129c:	90                   	nop
    outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF);
c010129d:	8b 45 0c             	mov    0xc(%ebp),%eax
c01012a0:	c1 e8 10             	shr    $0x10,%eax
c01012a3:	0f b6 c0             	movzbl %al,%eax
c01012a6:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c01012aa:	83 c2 05             	add    $0x5,%edx
c01012ad:	0f b7 d2             	movzwl %dx,%edx
c01012b0:	66 89 55 e6          	mov    %dx,-0x1a(%ebp)
c01012b4:	88 45 e5             	mov    %al,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01012b7:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c01012bb:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c01012bf:	ee                   	out    %al,(%dx)
}
c01012c0:	90                   	nop
    outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF));
c01012c1:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c01012c4:	c0 e0 04             	shl    $0x4,%al
c01012c7:	24 10                	and    $0x10,%al
c01012c9:	88 c2                	mov    %al,%dl
c01012cb:	8b 45 0c             	mov    0xc(%ebp),%eax
c01012ce:	c1 e8 18             	shr    $0x18,%eax
c01012d1:	24 0f                	and    $0xf,%al
c01012d3:	08 d0                	or     %dl,%al
c01012d5:	0c e0                	or     $0xe0,%al
c01012d7:	0f b6 c0             	movzbl %al,%eax
c01012da:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c01012de:	83 c2 06             	add    $0x6,%edx
c01012e1:	0f b7 d2             	movzwl %dx,%edx
c01012e4:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c01012e8:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01012eb:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c01012ef:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c01012f3:	ee                   	out    %al,(%dx)
}
c01012f4:	90                   	nop
    outb(iobase + ISA_COMMAND, IDE_CMD_READ);
c01012f5:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c01012f9:	83 c0 07             	add    $0x7,%eax
c01012fc:	0f b7 c0             	movzwl %ax,%eax
c01012ff:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101303:	c6 45 ed 20          	movb   $0x20,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101307:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c010130b:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c010130f:	ee                   	out    %al,(%dx)
}
c0101310:	90                   	nop

    int ret = 0;
c0101311:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    for (; nsecs > 0; nsecs --, dst += SECTSIZE) {
c0101318:	eb 58                	jmp    c0101372 <ide_read_secs+0x232>
        if ((ret = ide_wait_ready(iobase, 1)) != 0) {
c010131a:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c010131e:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0101325:	00 
c0101326:	89 04 24             	mov    %eax,(%esp)
c0101329:	e8 2d fa ff ff       	call   c0100d5b <ide_wait_ready>
c010132e:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0101331:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0101335:	75 43                	jne    c010137a <ide_read_secs+0x23a>
            goto out;
        }
        insl(iobase, dst, SECTSIZE / sizeof(uint32_t));
c0101337:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c010133b:	89 45 d0             	mov    %eax,-0x30(%ebp)
c010133e:	8b 45 10             	mov    0x10(%ebp),%eax
c0101341:	89 45 cc             	mov    %eax,-0x34(%ebp)
c0101344:	c7 45 c8 80 00 00 00 	movl   $0x80,-0x38(%ebp)
    asm volatile (
c010134b:	8b 55 d0             	mov    -0x30(%ebp),%edx
c010134e:	8b 4d cc             	mov    -0x34(%ebp),%ecx
c0101351:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0101354:	89 cb                	mov    %ecx,%ebx
c0101356:	89 df                	mov    %ebx,%edi
c0101358:	89 c1                	mov    %eax,%ecx
c010135a:	fc                   	cld    
c010135b:	f2 6d                	repnz insl (%dx),%es:(%edi)
c010135d:	89 c8                	mov    %ecx,%eax
c010135f:	89 fb                	mov    %edi,%ebx
c0101361:	89 5d cc             	mov    %ebx,-0x34(%ebp)
c0101364:	89 45 c8             	mov    %eax,-0x38(%ebp)
}
c0101367:	90                   	nop
    for (; nsecs > 0; nsecs --, dst += SECTSIZE) {
c0101368:	ff 4d 14             	decl   0x14(%ebp)
c010136b:	81 45 10 00 02 00 00 	addl   $0x200,0x10(%ebp)
c0101372:	83 7d 14 00          	cmpl   $0x0,0x14(%ebp)
c0101376:	75 a2                	jne    c010131a <ide_read_secs+0x1da>
    }

out:
c0101378:	eb 01                	jmp    c010137b <ide_read_secs+0x23b>
            goto out;
c010137a:	90                   	nop
    return ret;
c010137b:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010137e:	83 c4 50             	add    $0x50,%esp
c0101381:	5b                   	pop    %ebx
c0101382:	5f                   	pop    %edi
c0101383:	5d                   	pop    %ebp
c0101384:	c3                   	ret    

c0101385 <ide_write_secs>:

int
ide_write_secs(unsigned short ideno, uint32_t secno, const void *src, size_t nsecs) {
c0101385:	f3 0f 1e fb          	endbr32 
c0101389:	55                   	push   %ebp
c010138a:	89 e5                	mov    %esp,%ebp
c010138c:	56                   	push   %esi
c010138d:	53                   	push   %ebx
c010138e:	83 ec 50             	sub    $0x50,%esp
c0101391:	8b 45 08             	mov    0x8(%ebp),%eax
c0101394:	66 89 45 c4          	mov    %ax,-0x3c(%ebp)
    assert(nsecs <= MAX_NSECS && VALID_IDE(ideno));
c0101398:	81 7d 14 80 00 00 00 	cmpl   $0x80,0x14(%ebp)
c010139f:	77 23                	ja     c01013c4 <ide_write_secs+0x3f>
c01013a1:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c01013a5:	83 f8 03             	cmp    $0x3,%eax
c01013a8:	77 1a                	ja     c01013c4 <ide_write_secs+0x3f>
c01013aa:	0f b7 55 c4          	movzwl -0x3c(%ebp),%edx
c01013ae:	89 d0                	mov    %edx,%eax
c01013b0:	c1 e0 03             	shl    $0x3,%eax
c01013b3:	29 d0                	sub    %edx,%eax
c01013b5:	c1 e0 03             	shl    $0x3,%eax
c01013b8:	05 40 64 12 c0       	add    $0xc0126440,%eax
c01013bd:	0f b6 00             	movzbl (%eax),%eax
c01013c0:	84 c0                	test   %al,%al
c01013c2:	75 24                	jne    c01013e8 <ide_write_secs+0x63>
c01013c4:	c7 44 24 0c 7c 93 10 	movl   $0xc010937c,0xc(%esp)
c01013cb:	c0 
c01013cc:	c7 44 24 08 37 93 10 	movl   $0xc0109337,0x8(%esp)
c01013d3:	c0 
c01013d4:	c7 44 24 04 da 00 00 	movl   $0xda,0x4(%esp)
c01013db:	00 
c01013dc:	c7 04 24 4c 93 10 c0 	movl   $0xc010934c,(%esp)
c01013e3:	e8 5d f0 ff ff       	call   c0100445 <__panic>
    assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS);
c01013e8:	81 7d 0c ff ff ff 0f 	cmpl   $0xfffffff,0xc(%ebp)
c01013ef:	77 0f                	ja     c0101400 <ide_write_secs+0x7b>
c01013f1:	8b 55 0c             	mov    0xc(%ebp),%edx
c01013f4:	8b 45 14             	mov    0x14(%ebp),%eax
c01013f7:	01 d0                	add    %edx,%eax
c01013f9:	3d 00 00 00 10       	cmp    $0x10000000,%eax
c01013fe:	76 24                	jbe    c0101424 <ide_write_secs+0x9f>
c0101400:	c7 44 24 0c a4 93 10 	movl   $0xc01093a4,0xc(%esp)
c0101407:	c0 
c0101408:	c7 44 24 08 37 93 10 	movl   $0xc0109337,0x8(%esp)
c010140f:	c0 
c0101410:	c7 44 24 04 db 00 00 	movl   $0xdb,0x4(%esp)
c0101417:	00 
c0101418:	c7 04 24 4c 93 10 c0 	movl   $0xc010934c,(%esp)
c010141f:	e8 21 f0 ff ff       	call   c0100445 <__panic>
    unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno);
c0101424:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101428:	d1 e8                	shr    %eax
c010142a:	0f b7 c0             	movzwl %ax,%eax
c010142d:	8b 04 85 ec 92 10 c0 	mov    -0x3fef6d14(,%eax,4),%eax
c0101434:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
c0101438:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c010143c:	d1 e8                	shr    %eax
c010143e:	0f b7 c0             	movzwl %ax,%eax
c0101441:	0f b7 04 85 ee 92 10 	movzwl -0x3fef6d12(,%eax,4),%eax
c0101448:	c0 
c0101449:	66 89 45 f0          	mov    %ax,-0x10(%ebp)

    ide_wait_ready(iobase, 0);
c010144d:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101451:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0101458:	00 
c0101459:	89 04 24             	mov    %eax,(%esp)
c010145c:	e8 fa f8 ff ff       	call   c0100d5b <ide_wait_ready>

    // generate interrupt
    outb(ioctrl + ISA_CTRL, 0);
c0101461:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101464:	83 c0 02             	add    $0x2,%eax
c0101467:	0f b7 c0             	movzwl %ax,%eax
c010146a:	66 89 45 d6          	mov    %ax,-0x2a(%ebp)
c010146e:	c6 45 d5 00          	movb   $0x0,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101472:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0101476:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c010147a:	ee                   	out    %al,(%dx)
}
c010147b:	90                   	nop
    outb(iobase + ISA_SECCNT, nsecs);
c010147c:	8b 45 14             	mov    0x14(%ebp),%eax
c010147f:	0f b6 c0             	movzbl %al,%eax
c0101482:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101486:	83 c2 02             	add    $0x2,%edx
c0101489:	0f b7 d2             	movzwl %dx,%edx
c010148c:	66 89 55 da          	mov    %dx,-0x26(%ebp)
c0101490:	88 45 d9             	mov    %al,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101493:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0101497:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c010149b:	ee                   	out    %al,(%dx)
}
c010149c:	90                   	nop
    outb(iobase + ISA_SECTOR, secno & 0xFF);
c010149d:	8b 45 0c             	mov    0xc(%ebp),%eax
c01014a0:	0f b6 c0             	movzbl %al,%eax
c01014a3:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c01014a7:	83 c2 03             	add    $0x3,%edx
c01014aa:	0f b7 d2             	movzwl %dx,%edx
c01014ad:	66 89 55 de          	mov    %dx,-0x22(%ebp)
c01014b1:	88 45 dd             	mov    %al,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01014b4:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c01014b8:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c01014bc:	ee                   	out    %al,(%dx)
}
c01014bd:	90                   	nop
    outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF);
c01014be:	8b 45 0c             	mov    0xc(%ebp),%eax
c01014c1:	c1 e8 08             	shr    $0x8,%eax
c01014c4:	0f b6 c0             	movzbl %al,%eax
c01014c7:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c01014cb:	83 c2 04             	add    $0x4,%edx
c01014ce:	0f b7 d2             	movzwl %dx,%edx
c01014d1:	66 89 55 e2          	mov    %dx,-0x1e(%ebp)
c01014d5:	88 45 e1             	mov    %al,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01014d8:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c01014dc:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c01014e0:	ee                   	out    %al,(%dx)
}
c01014e1:	90                   	nop
    outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF);
c01014e2:	8b 45 0c             	mov    0xc(%ebp),%eax
c01014e5:	c1 e8 10             	shr    $0x10,%eax
c01014e8:	0f b6 c0             	movzbl %al,%eax
c01014eb:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c01014ef:	83 c2 05             	add    $0x5,%edx
c01014f2:	0f b7 d2             	movzwl %dx,%edx
c01014f5:	66 89 55 e6          	mov    %dx,-0x1a(%ebp)
c01014f9:	88 45 e5             	mov    %al,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01014fc:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101500:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101504:	ee                   	out    %al,(%dx)
}
c0101505:	90                   	nop
    outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF));
c0101506:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0101509:	c0 e0 04             	shl    $0x4,%al
c010150c:	24 10                	and    $0x10,%al
c010150e:	88 c2                	mov    %al,%dl
c0101510:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101513:	c1 e8 18             	shr    $0x18,%eax
c0101516:	24 0f                	and    $0xf,%al
c0101518:	08 d0                	or     %dl,%al
c010151a:	0c e0                	or     $0xe0,%al
c010151c:	0f b6 c0             	movzbl %al,%eax
c010151f:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101523:	83 c2 06             	add    $0x6,%edx
c0101526:	0f b7 d2             	movzwl %dx,%edx
c0101529:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c010152d:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101530:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0101534:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0101538:	ee                   	out    %al,(%dx)
}
c0101539:	90                   	nop
    outb(iobase + ISA_COMMAND, IDE_CMD_WRITE);
c010153a:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c010153e:	83 c0 07             	add    $0x7,%eax
c0101541:	0f b7 c0             	movzwl %ax,%eax
c0101544:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101548:	c6 45 ed 30          	movb   $0x30,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010154c:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101550:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101554:	ee                   	out    %al,(%dx)
}
c0101555:	90                   	nop

    int ret = 0;
c0101556:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    for (; nsecs > 0; nsecs --, src += SECTSIZE) {
c010155d:	eb 58                	jmp    c01015b7 <ide_write_secs+0x232>
        if ((ret = ide_wait_ready(iobase, 1)) != 0) {
c010155f:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101563:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010156a:	00 
c010156b:	89 04 24             	mov    %eax,(%esp)
c010156e:	e8 e8 f7 ff ff       	call   c0100d5b <ide_wait_ready>
c0101573:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0101576:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010157a:	75 43                	jne    c01015bf <ide_write_secs+0x23a>
            goto out;
        }
        outsl(iobase, src, SECTSIZE / sizeof(uint32_t));
c010157c:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101580:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0101583:	8b 45 10             	mov    0x10(%ebp),%eax
c0101586:	89 45 cc             	mov    %eax,-0x34(%ebp)
c0101589:	c7 45 c8 80 00 00 00 	movl   $0x80,-0x38(%ebp)
    asm volatile ("outw %0, %1" :: "a" (data), "d" (port) : "memory");
}

static inline void
outsl(uint32_t port, const void *addr, int cnt) {
    asm volatile (
c0101590:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0101593:	8b 4d cc             	mov    -0x34(%ebp),%ecx
c0101596:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0101599:	89 cb                	mov    %ecx,%ebx
c010159b:	89 de                	mov    %ebx,%esi
c010159d:	89 c1                	mov    %eax,%ecx
c010159f:	fc                   	cld    
c01015a0:	f2 6f                	repnz outsl %ds:(%esi),(%dx)
c01015a2:	89 c8                	mov    %ecx,%eax
c01015a4:	89 f3                	mov    %esi,%ebx
c01015a6:	89 5d cc             	mov    %ebx,-0x34(%ebp)
c01015a9:	89 45 c8             	mov    %eax,-0x38(%ebp)
        "cld;"
        "repne; outsl;"
        : "=S" (addr), "=c" (cnt)
        : "d" (port), "0" (addr), "1" (cnt)
        : "memory", "cc");
}
c01015ac:	90                   	nop
    for (; nsecs > 0; nsecs --, src += SECTSIZE) {
c01015ad:	ff 4d 14             	decl   0x14(%ebp)
c01015b0:	81 45 10 00 02 00 00 	addl   $0x200,0x10(%ebp)
c01015b7:	83 7d 14 00          	cmpl   $0x0,0x14(%ebp)
c01015bb:	75 a2                	jne    c010155f <ide_write_secs+0x1da>
    }

out:
c01015bd:	eb 01                	jmp    c01015c0 <ide_write_secs+0x23b>
            goto out;
c01015bf:	90                   	nop
    return ret;
c01015c0:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01015c3:	83 c4 50             	add    $0x50,%esp
c01015c6:	5b                   	pop    %ebx
c01015c7:	5e                   	pop    %esi
c01015c8:	5d                   	pop    %ebp
c01015c9:	c3                   	ret    

c01015ca <clock_init>:
/* *
 * clock_init - initialize 8253 clock to interrupt 100 times per second,
 * and then enable IRQ_TIMER.
 * */
void
clock_init(void) {
c01015ca:	f3 0f 1e fb          	endbr32 
c01015ce:	55                   	push   %ebp
c01015cf:	89 e5                	mov    %esp,%ebp
c01015d1:	83 ec 28             	sub    $0x28,%esp
c01015d4:	66 c7 45 ee 43 00    	movw   $0x43,-0x12(%ebp)
c01015da:	c6 45 ed 34          	movb   $0x34,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01015de:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c01015e2:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c01015e6:	ee                   	out    %al,(%dx)
}
c01015e7:	90                   	nop
c01015e8:	66 c7 45 f2 40 00    	movw   $0x40,-0xe(%ebp)
c01015ee:	c6 45 f1 9c          	movb   $0x9c,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01015f2:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c01015f6:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c01015fa:	ee                   	out    %al,(%dx)
}
c01015fb:	90                   	nop
c01015fc:	66 c7 45 f6 40 00    	movw   $0x40,-0xa(%ebp)
c0101602:	c6 45 f5 2e          	movb   $0x2e,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101606:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c010160a:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c010160e:	ee                   	out    %al,(%dx)
}
c010160f:	90                   	nop
    outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
    outb(IO_TIMER1, TIMER_DIV(100) % 256);
    outb(IO_TIMER1, TIMER_DIV(100) / 256);

    // initialize time counter 'ticks' to zero
    ticks = 0;
c0101610:	c7 05 1c 70 12 c0 00 	movl   $0x0,0xc012701c
c0101617:	00 00 00 

    cprintf("++ setup timer interrupts\n");
c010161a:	c7 04 24 de 93 10 c0 	movl   $0xc01093de,(%esp)
c0101621:	e8 b3 ec ff ff       	call   c01002d9 <cprintf>
    pic_enable(IRQ_TIMER);
c0101626:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c010162d:	e8 95 09 00 00       	call   c0101fc7 <pic_enable>
}
c0101632:	90                   	nop
c0101633:	c9                   	leave  
c0101634:	c3                   	ret    

c0101635 <__intr_save>:
#include <x86.h>
#include <intr.h>
#include <mmu.h>

static inline bool
__intr_save(void) {
c0101635:	55                   	push   %ebp
c0101636:	89 e5                	mov    %esp,%ebp
c0101638:	83 ec 18             	sub    $0x18,%esp
}

static inline uint32_t
read_eflags(void) {
    uint32_t eflags;
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c010163b:	9c                   	pushf  
c010163c:	58                   	pop    %eax
c010163d:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c0101640:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c0101643:	25 00 02 00 00       	and    $0x200,%eax
c0101648:	85 c0                	test   %eax,%eax
c010164a:	74 0c                	je     c0101658 <__intr_save+0x23>
        intr_disable();
c010164c:	e8 05 0b 00 00       	call   c0102156 <intr_disable>
        return 1;
c0101651:	b8 01 00 00 00       	mov    $0x1,%eax
c0101656:	eb 05                	jmp    c010165d <__intr_save+0x28>
    }
    return 0;
c0101658:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010165d:	c9                   	leave  
c010165e:	c3                   	ret    

c010165f <__intr_restore>:

static inline void
__intr_restore(bool flag) {
c010165f:	55                   	push   %ebp
c0101660:	89 e5                	mov    %esp,%ebp
c0101662:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c0101665:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0101669:	74 05                	je     c0101670 <__intr_restore+0x11>
        intr_enable();
c010166b:	e8 da 0a 00 00       	call   c010214a <intr_enable>
    }
}
c0101670:	90                   	nop
c0101671:	c9                   	leave  
c0101672:	c3                   	ret    

c0101673 <delay>:
#include <memlayout.h>
#include <sync.h>

/* stupid I/O delay routine necessitated by historical PC design flaws */
static void
delay(void) {
c0101673:	f3 0f 1e fb          	endbr32 
c0101677:	55                   	push   %ebp
c0101678:	89 e5                	mov    %esp,%ebp
c010167a:	83 ec 10             	sub    $0x10,%esp
c010167d:	66 c7 45 f2 84 00    	movw   $0x84,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101683:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101687:	89 c2                	mov    %eax,%edx
c0101689:	ec                   	in     (%dx),%al
c010168a:	88 45 f1             	mov    %al,-0xf(%ebp)
c010168d:	66 c7 45 f6 84 00    	movw   $0x84,-0xa(%ebp)
c0101693:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101697:	89 c2                	mov    %eax,%edx
c0101699:	ec                   	in     (%dx),%al
c010169a:	88 45 f5             	mov    %al,-0xb(%ebp)
c010169d:	66 c7 45 fa 84 00    	movw   $0x84,-0x6(%ebp)
c01016a3:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c01016a7:	89 c2                	mov    %eax,%edx
c01016a9:	ec                   	in     (%dx),%al
c01016aa:	88 45 f9             	mov    %al,-0x7(%ebp)
c01016ad:	66 c7 45 fe 84 00    	movw   $0x84,-0x2(%ebp)
c01016b3:	0f b7 45 fe          	movzwl -0x2(%ebp),%eax
c01016b7:	89 c2                	mov    %eax,%edx
c01016b9:	ec                   	in     (%dx),%al
c01016ba:	88 45 fd             	mov    %al,-0x3(%ebp)
    inb(0x84);
    inb(0x84);
    inb(0x84);
    inb(0x84);
}
c01016bd:	90                   	nop
c01016be:	c9                   	leave  
c01016bf:	c3                   	ret    

c01016c0 <cga_init>:
static uint16_t addr_6845;

/* TEXT-mode CGA/VGA display output */

static void
cga_init(void) {
c01016c0:	f3 0f 1e fb          	endbr32 
c01016c4:	55                   	push   %ebp
c01016c5:	89 e5                	mov    %esp,%ebp
c01016c7:	83 ec 20             	sub    $0x20,%esp
    volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE);
c01016ca:	c7 45 fc 00 80 0b c0 	movl   $0xc00b8000,-0x4(%ebp)
    uint16_t was = *cp;
c01016d1:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01016d4:	0f b7 00             	movzwl (%eax),%eax
c01016d7:	66 89 45 fa          	mov    %ax,-0x6(%ebp)
    *cp = (uint16_t) 0xA55A;
c01016db:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01016de:	66 c7 00 5a a5       	movw   $0xa55a,(%eax)
    if (*cp != 0xA55A) {
c01016e3:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01016e6:	0f b7 00             	movzwl (%eax),%eax
c01016e9:	0f b7 c0             	movzwl %ax,%eax
c01016ec:	3d 5a a5 00 00       	cmp    $0xa55a,%eax
c01016f1:	74 12                	je     c0101705 <cga_init+0x45>
        cp = (uint16_t*)(MONO_BUF + KERNBASE);
c01016f3:	c7 45 fc 00 00 0b c0 	movl   $0xc00b0000,-0x4(%ebp)
        addr_6845 = MONO_BASE;
c01016fa:	66 c7 05 26 65 12 c0 	movw   $0x3b4,0xc0126526
c0101701:	b4 03 
c0101703:	eb 13                	jmp    c0101718 <cga_init+0x58>
    } else {
        *cp = was;
c0101705:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0101708:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c010170c:	66 89 10             	mov    %dx,(%eax)
        addr_6845 = CGA_BASE;
c010170f:	66 c7 05 26 65 12 c0 	movw   $0x3d4,0xc0126526
c0101716:	d4 03 
    }

    // Extract cursor location
    uint32_t pos;
    outb(addr_6845, 14);
c0101718:	0f b7 05 26 65 12 c0 	movzwl 0xc0126526,%eax
c010171f:	66 89 45 e6          	mov    %ax,-0x1a(%ebp)
c0101723:	c6 45 e5 0e          	movb   $0xe,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101727:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c010172b:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c010172f:	ee                   	out    %al,(%dx)
}
c0101730:	90                   	nop
    pos = inb(addr_6845 + 1) << 8;
c0101731:	0f b7 05 26 65 12 c0 	movzwl 0xc0126526,%eax
c0101738:	40                   	inc    %eax
c0101739:	0f b7 c0             	movzwl %ax,%eax
c010173c:	66 89 45 ea          	mov    %ax,-0x16(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101740:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0101744:	89 c2                	mov    %eax,%edx
c0101746:	ec                   	in     (%dx),%al
c0101747:	88 45 e9             	mov    %al,-0x17(%ebp)
    return data;
c010174a:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c010174e:	0f b6 c0             	movzbl %al,%eax
c0101751:	c1 e0 08             	shl    $0x8,%eax
c0101754:	89 45 f4             	mov    %eax,-0xc(%ebp)
    outb(addr_6845, 15);
c0101757:	0f b7 05 26 65 12 c0 	movzwl 0xc0126526,%eax
c010175e:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101762:	c6 45 ed 0f          	movb   $0xf,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101766:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c010176a:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c010176e:	ee                   	out    %al,(%dx)
}
c010176f:	90                   	nop
    pos |= inb(addr_6845 + 1);
c0101770:	0f b7 05 26 65 12 c0 	movzwl 0xc0126526,%eax
c0101777:	40                   	inc    %eax
c0101778:	0f b7 c0             	movzwl %ax,%eax
c010177b:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c010177f:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101783:	89 c2                	mov    %eax,%edx
c0101785:	ec                   	in     (%dx),%al
c0101786:	88 45 f1             	mov    %al,-0xf(%ebp)
    return data;
c0101789:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c010178d:	0f b6 c0             	movzbl %al,%eax
c0101790:	09 45 f4             	or     %eax,-0xc(%ebp)

    crt_buf = (uint16_t*) cp;
c0101793:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0101796:	a3 20 65 12 c0       	mov    %eax,0xc0126520
    crt_pos = pos;
c010179b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010179e:	0f b7 c0             	movzwl %ax,%eax
c01017a1:	66 a3 24 65 12 c0    	mov    %ax,0xc0126524
}
c01017a7:	90                   	nop
c01017a8:	c9                   	leave  
c01017a9:	c3                   	ret    

c01017aa <serial_init>:

static bool serial_exists = 0;

static void
serial_init(void) {
c01017aa:	f3 0f 1e fb          	endbr32 
c01017ae:	55                   	push   %ebp
c01017af:	89 e5                	mov    %esp,%ebp
c01017b1:	83 ec 48             	sub    $0x48,%esp
c01017b4:	66 c7 45 d2 fa 03    	movw   $0x3fa,-0x2e(%ebp)
c01017ba:	c6 45 d1 00          	movb   $0x0,-0x2f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01017be:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c01017c2:	0f b7 55 d2          	movzwl -0x2e(%ebp),%edx
c01017c6:	ee                   	out    %al,(%dx)
}
c01017c7:	90                   	nop
c01017c8:	66 c7 45 d6 fb 03    	movw   $0x3fb,-0x2a(%ebp)
c01017ce:	c6 45 d5 80          	movb   $0x80,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01017d2:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c01017d6:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c01017da:	ee                   	out    %al,(%dx)
}
c01017db:	90                   	nop
c01017dc:	66 c7 45 da f8 03    	movw   $0x3f8,-0x26(%ebp)
c01017e2:	c6 45 d9 0c          	movb   $0xc,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01017e6:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c01017ea:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c01017ee:	ee                   	out    %al,(%dx)
}
c01017ef:	90                   	nop
c01017f0:	66 c7 45 de f9 03    	movw   $0x3f9,-0x22(%ebp)
c01017f6:	c6 45 dd 00          	movb   $0x0,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01017fa:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c01017fe:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0101802:	ee                   	out    %al,(%dx)
}
c0101803:	90                   	nop
c0101804:	66 c7 45 e2 fb 03    	movw   $0x3fb,-0x1e(%ebp)
c010180a:	c6 45 e1 03          	movb   $0x3,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010180e:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0101812:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c0101816:	ee                   	out    %al,(%dx)
}
c0101817:	90                   	nop
c0101818:	66 c7 45 e6 fc 03    	movw   $0x3fc,-0x1a(%ebp)
c010181e:	c6 45 e5 00          	movb   $0x0,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101822:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101826:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c010182a:	ee                   	out    %al,(%dx)
}
c010182b:	90                   	nop
c010182c:	66 c7 45 ea f9 03    	movw   $0x3f9,-0x16(%ebp)
c0101832:	c6 45 e9 01          	movb   $0x1,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101836:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c010183a:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c010183e:	ee                   	out    %al,(%dx)
}
c010183f:	90                   	nop
c0101840:	66 c7 45 ee fd 03    	movw   $0x3fd,-0x12(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101846:	0f b7 45 ee          	movzwl -0x12(%ebp),%eax
c010184a:	89 c2                	mov    %eax,%edx
c010184c:	ec                   	in     (%dx),%al
c010184d:	88 45 ed             	mov    %al,-0x13(%ebp)
    return data;
c0101850:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
    // Enable rcv interrupts
    outb(COM1 + COM_IER, COM_IER_RDI);

    // Clear any preexisting overrun indications and interrupts
    // Serial port doesn't exist if COM_LSR returns 0xFF
    serial_exists = (inb(COM1 + COM_LSR) != 0xFF);
c0101854:	3c ff                	cmp    $0xff,%al
c0101856:	0f 95 c0             	setne  %al
c0101859:	0f b6 c0             	movzbl %al,%eax
c010185c:	a3 28 65 12 c0       	mov    %eax,0xc0126528
c0101861:	66 c7 45 f2 fa 03    	movw   $0x3fa,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101867:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c010186b:	89 c2                	mov    %eax,%edx
c010186d:	ec                   	in     (%dx),%al
c010186e:	88 45 f1             	mov    %al,-0xf(%ebp)
c0101871:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
c0101877:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010187b:	89 c2                	mov    %eax,%edx
c010187d:	ec                   	in     (%dx),%al
c010187e:	88 45 f5             	mov    %al,-0xb(%ebp)
    (void) inb(COM1+COM_IIR);
    (void) inb(COM1+COM_RX);

    if (serial_exists) {
c0101881:	a1 28 65 12 c0       	mov    0xc0126528,%eax
c0101886:	85 c0                	test   %eax,%eax
c0101888:	74 0c                	je     c0101896 <serial_init+0xec>
        pic_enable(IRQ_COM1);
c010188a:	c7 04 24 04 00 00 00 	movl   $0x4,(%esp)
c0101891:	e8 31 07 00 00       	call   c0101fc7 <pic_enable>
    }
}
c0101896:	90                   	nop
c0101897:	c9                   	leave  
c0101898:	c3                   	ret    

c0101899 <lpt_putc_sub>:

static void
lpt_putc_sub(int c) {
c0101899:	f3 0f 1e fb          	endbr32 
c010189d:	55                   	push   %ebp
c010189e:	89 e5                	mov    %esp,%ebp
c01018a0:	83 ec 20             	sub    $0x20,%esp
    int i;
    for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {
c01018a3:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c01018aa:	eb 08                	jmp    c01018b4 <lpt_putc_sub+0x1b>
        delay();
c01018ac:	e8 c2 fd ff ff       	call   c0101673 <delay>
    for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {
c01018b1:	ff 45 fc             	incl   -0x4(%ebp)
c01018b4:	66 c7 45 fa 79 03    	movw   $0x379,-0x6(%ebp)
c01018ba:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c01018be:	89 c2                	mov    %eax,%edx
c01018c0:	ec                   	in     (%dx),%al
c01018c1:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c01018c4:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c01018c8:	84 c0                	test   %al,%al
c01018ca:	78 09                	js     c01018d5 <lpt_putc_sub+0x3c>
c01018cc:	81 7d fc ff 31 00 00 	cmpl   $0x31ff,-0x4(%ebp)
c01018d3:	7e d7                	jle    c01018ac <lpt_putc_sub+0x13>
    }
    outb(LPTPORT + 0, c);
c01018d5:	8b 45 08             	mov    0x8(%ebp),%eax
c01018d8:	0f b6 c0             	movzbl %al,%eax
c01018db:	66 c7 45 ee 78 03    	movw   $0x378,-0x12(%ebp)
c01018e1:	88 45 ed             	mov    %al,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01018e4:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c01018e8:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c01018ec:	ee                   	out    %al,(%dx)
}
c01018ed:	90                   	nop
c01018ee:	66 c7 45 f2 7a 03    	movw   $0x37a,-0xe(%ebp)
c01018f4:	c6 45 f1 0d          	movb   $0xd,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01018f8:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c01018fc:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101900:	ee                   	out    %al,(%dx)
}
c0101901:	90                   	nop
c0101902:	66 c7 45 f6 7a 03    	movw   $0x37a,-0xa(%ebp)
c0101908:	c6 45 f5 08          	movb   $0x8,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010190c:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c0101910:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101914:	ee                   	out    %al,(%dx)
}
c0101915:	90                   	nop
    outb(LPTPORT + 2, 0x08 | 0x04 | 0x01);
    outb(LPTPORT + 2, 0x08);
}
c0101916:	90                   	nop
c0101917:	c9                   	leave  
c0101918:	c3                   	ret    

c0101919 <lpt_putc>:

/* lpt_putc - copy console output to parallel port */
static void
lpt_putc(int c) {
c0101919:	f3 0f 1e fb          	endbr32 
c010191d:	55                   	push   %ebp
c010191e:	89 e5                	mov    %esp,%ebp
c0101920:	83 ec 04             	sub    $0x4,%esp
    if (c != '\b') {
c0101923:	83 7d 08 08          	cmpl   $0x8,0x8(%ebp)
c0101927:	74 0d                	je     c0101936 <lpt_putc+0x1d>
        lpt_putc_sub(c);
c0101929:	8b 45 08             	mov    0x8(%ebp),%eax
c010192c:	89 04 24             	mov    %eax,(%esp)
c010192f:	e8 65 ff ff ff       	call   c0101899 <lpt_putc_sub>
    else {
        lpt_putc_sub('\b');
        lpt_putc_sub(' ');
        lpt_putc_sub('\b');
    }
}
c0101934:	eb 24                	jmp    c010195a <lpt_putc+0x41>
        lpt_putc_sub('\b');
c0101936:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c010193d:	e8 57 ff ff ff       	call   c0101899 <lpt_putc_sub>
        lpt_putc_sub(' ');
c0101942:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c0101949:	e8 4b ff ff ff       	call   c0101899 <lpt_putc_sub>
        lpt_putc_sub('\b');
c010194e:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c0101955:	e8 3f ff ff ff       	call   c0101899 <lpt_putc_sub>
}
c010195a:	90                   	nop
c010195b:	c9                   	leave  
c010195c:	c3                   	ret    

c010195d <cga_putc>:

/* cga_putc - print character to console */
static void
cga_putc(int c) {
c010195d:	f3 0f 1e fb          	endbr32 
c0101961:	55                   	push   %ebp
c0101962:	89 e5                	mov    %esp,%ebp
c0101964:	53                   	push   %ebx
c0101965:	83 ec 34             	sub    $0x34,%esp
    // set black on white
    if (!(c & ~0xFF)) {
c0101968:	8b 45 08             	mov    0x8(%ebp),%eax
c010196b:	25 00 ff ff ff       	and    $0xffffff00,%eax
c0101970:	85 c0                	test   %eax,%eax
c0101972:	75 07                	jne    c010197b <cga_putc+0x1e>
        c |= 0x0700;
c0101974:	81 4d 08 00 07 00 00 	orl    $0x700,0x8(%ebp)
    }

    switch (c & 0xff) {
c010197b:	8b 45 08             	mov    0x8(%ebp),%eax
c010197e:	0f b6 c0             	movzbl %al,%eax
c0101981:	83 f8 0d             	cmp    $0xd,%eax
c0101984:	74 72                	je     c01019f8 <cga_putc+0x9b>
c0101986:	83 f8 0d             	cmp    $0xd,%eax
c0101989:	0f 8f a3 00 00 00    	jg     c0101a32 <cga_putc+0xd5>
c010198f:	83 f8 08             	cmp    $0x8,%eax
c0101992:	74 0a                	je     c010199e <cga_putc+0x41>
c0101994:	83 f8 0a             	cmp    $0xa,%eax
c0101997:	74 4c                	je     c01019e5 <cga_putc+0x88>
c0101999:	e9 94 00 00 00       	jmp    c0101a32 <cga_putc+0xd5>
    case '\b':
        if (crt_pos > 0) {
c010199e:	0f b7 05 24 65 12 c0 	movzwl 0xc0126524,%eax
c01019a5:	85 c0                	test   %eax,%eax
c01019a7:	0f 84 af 00 00 00    	je     c0101a5c <cga_putc+0xff>
            crt_pos --;
c01019ad:	0f b7 05 24 65 12 c0 	movzwl 0xc0126524,%eax
c01019b4:	48                   	dec    %eax
c01019b5:	0f b7 c0             	movzwl %ax,%eax
c01019b8:	66 a3 24 65 12 c0    	mov    %ax,0xc0126524
            crt_buf[crt_pos] = (c & ~0xff) | ' ';
c01019be:	8b 45 08             	mov    0x8(%ebp),%eax
c01019c1:	98                   	cwtl   
c01019c2:	25 00 ff ff ff       	and    $0xffffff00,%eax
c01019c7:	98                   	cwtl   
c01019c8:	83 c8 20             	or     $0x20,%eax
c01019cb:	98                   	cwtl   
c01019cc:	8b 15 20 65 12 c0    	mov    0xc0126520,%edx
c01019d2:	0f b7 0d 24 65 12 c0 	movzwl 0xc0126524,%ecx
c01019d9:	01 c9                	add    %ecx,%ecx
c01019db:	01 ca                	add    %ecx,%edx
c01019dd:	0f b7 c0             	movzwl %ax,%eax
c01019e0:	66 89 02             	mov    %ax,(%edx)
        }
        break;
c01019e3:	eb 77                	jmp    c0101a5c <cga_putc+0xff>
    case '\n':
        crt_pos += CRT_COLS;
c01019e5:	0f b7 05 24 65 12 c0 	movzwl 0xc0126524,%eax
c01019ec:	83 c0 50             	add    $0x50,%eax
c01019ef:	0f b7 c0             	movzwl %ax,%eax
c01019f2:	66 a3 24 65 12 c0    	mov    %ax,0xc0126524
    case '\r':
        crt_pos -= (crt_pos % CRT_COLS);
c01019f8:	0f b7 1d 24 65 12 c0 	movzwl 0xc0126524,%ebx
c01019ff:	0f b7 0d 24 65 12 c0 	movzwl 0xc0126524,%ecx
c0101a06:	ba cd cc cc cc       	mov    $0xcccccccd,%edx
c0101a0b:	89 c8                	mov    %ecx,%eax
c0101a0d:	f7 e2                	mul    %edx
c0101a0f:	c1 ea 06             	shr    $0x6,%edx
c0101a12:	89 d0                	mov    %edx,%eax
c0101a14:	c1 e0 02             	shl    $0x2,%eax
c0101a17:	01 d0                	add    %edx,%eax
c0101a19:	c1 e0 04             	shl    $0x4,%eax
c0101a1c:	29 c1                	sub    %eax,%ecx
c0101a1e:	89 c8                	mov    %ecx,%eax
c0101a20:	0f b7 c0             	movzwl %ax,%eax
c0101a23:	29 c3                	sub    %eax,%ebx
c0101a25:	89 d8                	mov    %ebx,%eax
c0101a27:	0f b7 c0             	movzwl %ax,%eax
c0101a2a:	66 a3 24 65 12 c0    	mov    %ax,0xc0126524
        break;
c0101a30:	eb 2b                	jmp    c0101a5d <cga_putc+0x100>
    default:
        crt_buf[crt_pos ++] = c;     // write the character
c0101a32:	8b 0d 20 65 12 c0    	mov    0xc0126520,%ecx
c0101a38:	0f b7 05 24 65 12 c0 	movzwl 0xc0126524,%eax
c0101a3f:	8d 50 01             	lea    0x1(%eax),%edx
c0101a42:	0f b7 d2             	movzwl %dx,%edx
c0101a45:	66 89 15 24 65 12 c0 	mov    %dx,0xc0126524
c0101a4c:	01 c0                	add    %eax,%eax
c0101a4e:	8d 14 01             	lea    (%ecx,%eax,1),%edx
c0101a51:	8b 45 08             	mov    0x8(%ebp),%eax
c0101a54:	0f b7 c0             	movzwl %ax,%eax
c0101a57:	66 89 02             	mov    %ax,(%edx)
        break;
c0101a5a:	eb 01                	jmp    c0101a5d <cga_putc+0x100>
        break;
c0101a5c:	90                   	nop
    }

    // What is the purpose of this?
    if (crt_pos >= CRT_SIZE) {
c0101a5d:	0f b7 05 24 65 12 c0 	movzwl 0xc0126524,%eax
c0101a64:	3d cf 07 00 00       	cmp    $0x7cf,%eax
c0101a69:	76 5d                	jbe    c0101ac8 <cga_putc+0x16b>
        int i;
        memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t));
c0101a6b:	a1 20 65 12 c0       	mov    0xc0126520,%eax
c0101a70:	8d 90 a0 00 00 00    	lea    0xa0(%eax),%edx
c0101a76:	a1 20 65 12 c0       	mov    0xc0126520,%eax
c0101a7b:	c7 44 24 08 00 0f 00 	movl   $0xf00,0x8(%esp)
c0101a82:	00 
c0101a83:	89 54 24 04          	mov    %edx,0x4(%esp)
c0101a87:	89 04 24             	mov    %eax,(%esp)
c0101a8a:	e8 a1 6c 00 00       	call   c0108730 <memmove>
        for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) {
c0101a8f:	c7 45 f4 80 07 00 00 	movl   $0x780,-0xc(%ebp)
c0101a96:	eb 14                	jmp    c0101aac <cga_putc+0x14f>
            crt_buf[i] = 0x0700 | ' ';
c0101a98:	a1 20 65 12 c0       	mov    0xc0126520,%eax
c0101a9d:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0101aa0:	01 d2                	add    %edx,%edx
c0101aa2:	01 d0                	add    %edx,%eax
c0101aa4:	66 c7 00 20 07       	movw   $0x720,(%eax)
        for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) {
c0101aa9:	ff 45 f4             	incl   -0xc(%ebp)
c0101aac:	81 7d f4 cf 07 00 00 	cmpl   $0x7cf,-0xc(%ebp)
c0101ab3:	7e e3                	jle    c0101a98 <cga_putc+0x13b>
        }
        crt_pos -= CRT_COLS;
c0101ab5:	0f b7 05 24 65 12 c0 	movzwl 0xc0126524,%eax
c0101abc:	83 e8 50             	sub    $0x50,%eax
c0101abf:	0f b7 c0             	movzwl %ax,%eax
c0101ac2:	66 a3 24 65 12 c0    	mov    %ax,0xc0126524
    }

    // move that little blinky thing
    outb(addr_6845, 14);
c0101ac8:	0f b7 05 26 65 12 c0 	movzwl 0xc0126526,%eax
c0101acf:	66 89 45 e6          	mov    %ax,-0x1a(%ebp)
c0101ad3:	c6 45 e5 0e          	movb   $0xe,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101ad7:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101adb:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101adf:	ee                   	out    %al,(%dx)
}
c0101ae0:	90                   	nop
    outb(addr_6845 + 1, crt_pos >> 8);
c0101ae1:	0f b7 05 24 65 12 c0 	movzwl 0xc0126524,%eax
c0101ae8:	c1 e8 08             	shr    $0x8,%eax
c0101aeb:	0f b7 c0             	movzwl %ax,%eax
c0101aee:	0f b6 c0             	movzbl %al,%eax
c0101af1:	0f b7 15 26 65 12 c0 	movzwl 0xc0126526,%edx
c0101af8:	42                   	inc    %edx
c0101af9:	0f b7 d2             	movzwl %dx,%edx
c0101afc:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c0101b00:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101b03:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0101b07:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0101b0b:	ee                   	out    %al,(%dx)
}
c0101b0c:	90                   	nop
    outb(addr_6845, 15);
c0101b0d:	0f b7 05 26 65 12 c0 	movzwl 0xc0126526,%eax
c0101b14:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101b18:	c6 45 ed 0f          	movb   $0xf,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101b1c:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101b20:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101b24:	ee                   	out    %al,(%dx)
}
c0101b25:	90                   	nop
    outb(addr_6845 + 1, crt_pos);
c0101b26:	0f b7 05 24 65 12 c0 	movzwl 0xc0126524,%eax
c0101b2d:	0f b6 c0             	movzbl %al,%eax
c0101b30:	0f b7 15 26 65 12 c0 	movzwl 0xc0126526,%edx
c0101b37:	42                   	inc    %edx
c0101b38:	0f b7 d2             	movzwl %dx,%edx
c0101b3b:	66 89 55 f2          	mov    %dx,-0xe(%ebp)
c0101b3f:	88 45 f1             	mov    %al,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101b42:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0101b46:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101b4a:	ee                   	out    %al,(%dx)
}
c0101b4b:	90                   	nop
}
c0101b4c:	90                   	nop
c0101b4d:	83 c4 34             	add    $0x34,%esp
c0101b50:	5b                   	pop    %ebx
c0101b51:	5d                   	pop    %ebp
c0101b52:	c3                   	ret    

c0101b53 <serial_putc_sub>:

static void
serial_putc_sub(int c) {
c0101b53:	f3 0f 1e fb          	endbr32 
c0101b57:	55                   	push   %ebp
c0101b58:	89 e5                	mov    %esp,%ebp
c0101b5a:	83 ec 10             	sub    $0x10,%esp
    int i;
    for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) {
c0101b5d:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c0101b64:	eb 08                	jmp    c0101b6e <serial_putc_sub+0x1b>
        delay();
c0101b66:	e8 08 fb ff ff       	call   c0101673 <delay>
    for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) {
c0101b6b:	ff 45 fc             	incl   -0x4(%ebp)
c0101b6e:	66 c7 45 fa fd 03    	movw   $0x3fd,-0x6(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101b74:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c0101b78:	89 c2                	mov    %eax,%edx
c0101b7a:	ec                   	in     (%dx),%al
c0101b7b:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c0101b7e:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c0101b82:	0f b6 c0             	movzbl %al,%eax
c0101b85:	83 e0 20             	and    $0x20,%eax
c0101b88:	85 c0                	test   %eax,%eax
c0101b8a:	75 09                	jne    c0101b95 <serial_putc_sub+0x42>
c0101b8c:	81 7d fc ff 31 00 00 	cmpl   $0x31ff,-0x4(%ebp)
c0101b93:	7e d1                	jle    c0101b66 <serial_putc_sub+0x13>
    }
    outb(COM1 + COM_TX, c);
c0101b95:	8b 45 08             	mov    0x8(%ebp),%eax
c0101b98:	0f b6 c0             	movzbl %al,%eax
c0101b9b:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
c0101ba1:	88 45 f5             	mov    %al,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101ba4:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c0101ba8:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101bac:	ee                   	out    %al,(%dx)
}
c0101bad:	90                   	nop
}
c0101bae:	90                   	nop
c0101baf:	c9                   	leave  
c0101bb0:	c3                   	ret    

c0101bb1 <serial_putc>:

/* serial_putc - print character to serial port */
static void
serial_putc(int c) {
c0101bb1:	f3 0f 1e fb          	endbr32 
c0101bb5:	55                   	push   %ebp
c0101bb6:	89 e5                	mov    %esp,%ebp
c0101bb8:	83 ec 04             	sub    $0x4,%esp
    if (c != '\b') {
c0101bbb:	83 7d 08 08          	cmpl   $0x8,0x8(%ebp)
c0101bbf:	74 0d                	je     c0101bce <serial_putc+0x1d>
        serial_putc_sub(c);
c0101bc1:	8b 45 08             	mov    0x8(%ebp),%eax
c0101bc4:	89 04 24             	mov    %eax,(%esp)
c0101bc7:	e8 87 ff ff ff       	call   c0101b53 <serial_putc_sub>
    else {
        serial_putc_sub('\b');
        serial_putc_sub(' ');
        serial_putc_sub('\b');
    }
}
c0101bcc:	eb 24                	jmp    c0101bf2 <serial_putc+0x41>
        serial_putc_sub('\b');
c0101bce:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c0101bd5:	e8 79 ff ff ff       	call   c0101b53 <serial_putc_sub>
        serial_putc_sub(' ');
c0101bda:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c0101be1:	e8 6d ff ff ff       	call   c0101b53 <serial_putc_sub>
        serial_putc_sub('\b');
c0101be6:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c0101bed:	e8 61 ff ff ff       	call   c0101b53 <serial_putc_sub>
}
c0101bf2:	90                   	nop
c0101bf3:	c9                   	leave  
c0101bf4:	c3                   	ret    

c0101bf5 <cons_intr>:
/* *
 * cons_intr - called by device interrupt routines to feed input
 * characters into the circular console input buffer.
 * */
static void
cons_intr(int (*proc)(void)) {
c0101bf5:	f3 0f 1e fb          	endbr32 
c0101bf9:	55                   	push   %ebp
c0101bfa:	89 e5                	mov    %esp,%ebp
c0101bfc:	83 ec 18             	sub    $0x18,%esp
    int c;
    while ((c = (*proc)()) != -1) {
c0101bff:	eb 33                	jmp    c0101c34 <cons_intr+0x3f>
        if (c != 0) {
c0101c01:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0101c05:	74 2d                	je     c0101c34 <cons_intr+0x3f>
            cons.buf[cons.wpos ++] = c;
c0101c07:	a1 44 67 12 c0       	mov    0xc0126744,%eax
c0101c0c:	8d 50 01             	lea    0x1(%eax),%edx
c0101c0f:	89 15 44 67 12 c0    	mov    %edx,0xc0126744
c0101c15:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0101c18:	88 90 40 65 12 c0    	mov    %dl,-0x3fed9ac0(%eax)
            if (cons.wpos == CONSBUFSIZE) {
c0101c1e:	a1 44 67 12 c0       	mov    0xc0126744,%eax
c0101c23:	3d 00 02 00 00       	cmp    $0x200,%eax
c0101c28:	75 0a                	jne    c0101c34 <cons_intr+0x3f>
                cons.wpos = 0;
c0101c2a:	c7 05 44 67 12 c0 00 	movl   $0x0,0xc0126744
c0101c31:	00 00 00 
    while ((c = (*proc)()) != -1) {
c0101c34:	8b 45 08             	mov    0x8(%ebp),%eax
c0101c37:	ff d0                	call   *%eax
c0101c39:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0101c3c:	83 7d f4 ff          	cmpl   $0xffffffff,-0xc(%ebp)
c0101c40:	75 bf                	jne    c0101c01 <cons_intr+0xc>
            }
        }
    }
}
c0101c42:	90                   	nop
c0101c43:	90                   	nop
c0101c44:	c9                   	leave  
c0101c45:	c3                   	ret    

c0101c46 <serial_proc_data>:

/* serial_proc_data - get data from serial port */
static int
serial_proc_data(void) {
c0101c46:	f3 0f 1e fb          	endbr32 
c0101c4a:	55                   	push   %ebp
c0101c4b:	89 e5                	mov    %esp,%ebp
c0101c4d:	83 ec 10             	sub    $0x10,%esp
c0101c50:	66 c7 45 fa fd 03    	movw   $0x3fd,-0x6(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101c56:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c0101c5a:	89 c2                	mov    %eax,%edx
c0101c5c:	ec                   	in     (%dx),%al
c0101c5d:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c0101c60:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
    if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) {
c0101c64:	0f b6 c0             	movzbl %al,%eax
c0101c67:	83 e0 01             	and    $0x1,%eax
c0101c6a:	85 c0                	test   %eax,%eax
c0101c6c:	75 07                	jne    c0101c75 <serial_proc_data+0x2f>
        return -1;
c0101c6e:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c0101c73:	eb 2a                	jmp    c0101c9f <serial_proc_data+0x59>
c0101c75:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101c7b:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101c7f:	89 c2                	mov    %eax,%edx
c0101c81:	ec                   	in     (%dx),%al
c0101c82:	88 45 f5             	mov    %al,-0xb(%ebp)
    return data;
c0101c85:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
    }
    int c = inb(COM1 + COM_RX);
c0101c89:	0f b6 c0             	movzbl %al,%eax
c0101c8c:	89 45 fc             	mov    %eax,-0x4(%ebp)
    if (c == 127) {
c0101c8f:	83 7d fc 7f          	cmpl   $0x7f,-0x4(%ebp)
c0101c93:	75 07                	jne    c0101c9c <serial_proc_data+0x56>
        c = '\b';
c0101c95:	c7 45 fc 08 00 00 00 	movl   $0x8,-0x4(%ebp)
    }
    return c;
c0101c9c:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0101c9f:	c9                   	leave  
c0101ca0:	c3                   	ret    

c0101ca1 <serial_intr>:

/* serial_intr - try to feed input characters from serial port */
void
serial_intr(void) {
c0101ca1:	f3 0f 1e fb          	endbr32 
c0101ca5:	55                   	push   %ebp
c0101ca6:	89 e5                	mov    %esp,%ebp
c0101ca8:	83 ec 18             	sub    $0x18,%esp
    if (serial_exists) {
c0101cab:	a1 28 65 12 c0       	mov    0xc0126528,%eax
c0101cb0:	85 c0                	test   %eax,%eax
c0101cb2:	74 0c                	je     c0101cc0 <serial_intr+0x1f>
        cons_intr(serial_proc_data);
c0101cb4:	c7 04 24 46 1c 10 c0 	movl   $0xc0101c46,(%esp)
c0101cbb:	e8 35 ff ff ff       	call   c0101bf5 <cons_intr>
    }
}
c0101cc0:	90                   	nop
c0101cc1:	c9                   	leave  
c0101cc2:	c3                   	ret    

c0101cc3 <kbd_proc_data>:
 *
 * The kbd_proc_data() function gets data from the keyboard.
 * If we finish a character, return it, else 0. And return -1 if no data.
 * */
static int
kbd_proc_data(void) {
c0101cc3:	f3 0f 1e fb          	endbr32 
c0101cc7:	55                   	push   %ebp
c0101cc8:	89 e5                	mov    %esp,%ebp
c0101cca:	83 ec 38             	sub    $0x38,%esp
c0101ccd:	66 c7 45 f0 64 00    	movw   $0x64,-0x10(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101cd3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101cd6:	89 c2                	mov    %eax,%edx
c0101cd8:	ec                   	in     (%dx),%al
c0101cd9:	88 45 ef             	mov    %al,-0x11(%ebp)
    return data;
c0101cdc:	0f b6 45 ef          	movzbl -0x11(%ebp),%eax
    int c;
    uint8_t data;
    static uint32_t shift;

    if ((inb(KBSTATP) & KBS_DIB) == 0) {
c0101ce0:	0f b6 c0             	movzbl %al,%eax
c0101ce3:	83 e0 01             	and    $0x1,%eax
c0101ce6:	85 c0                	test   %eax,%eax
c0101ce8:	75 0a                	jne    c0101cf4 <kbd_proc_data+0x31>
        return -1;
c0101cea:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c0101cef:	e9 56 01 00 00       	jmp    c0101e4a <kbd_proc_data+0x187>
c0101cf4:	66 c7 45 ec 60 00    	movw   $0x60,-0x14(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101cfa:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101cfd:	89 c2                	mov    %eax,%edx
c0101cff:	ec                   	in     (%dx),%al
c0101d00:	88 45 eb             	mov    %al,-0x15(%ebp)
    return data;
c0101d03:	0f b6 45 eb          	movzbl -0x15(%ebp),%eax
    }

    data = inb(KBDATAP);
c0101d07:	88 45 f3             	mov    %al,-0xd(%ebp)

    if (data == 0xE0) {
c0101d0a:	80 7d f3 e0          	cmpb   $0xe0,-0xd(%ebp)
c0101d0e:	75 17                	jne    c0101d27 <kbd_proc_data+0x64>
        // E0 escape character
        shift |= E0ESC;
c0101d10:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101d15:	83 c8 40             	or     $0x40,%eax
c0101d18:	a3 48 67 12 c0       	mov    %eax,0xc0126748
        return 0;
c0101d1d:	b8 00 00 00 00       	mov    $0x0,%eax
c0101d22:	e9 23 01 00 00       	jmp    c0101e4a <kbd_proc_data+0x187>
    } else if (data & 0x80) {
c0101d27:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101d2b:	84 c0                	test   %al,%al
c0101d2d:	79 45                	jns    c0101d74 <kbd_proc_data+0xb1>
        // Key released
        data = (shift & E0ESC ? data : data & 0x7F);
c0101d2f:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101d34:	83 e0 40             	and    $0x40,%eax
c0101d37:	85 c0                	test   %eax,%eax
c0101d39:	75 08                	jne    c0101d43 <kbd_proc_data+0x80>
c0101d3b:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101d3f:	24 7f                	and    $0x7f,%al
c0101d41:	eb 04                	jmp    c0101d47 <kbd_proc_data+0x84>
c0101d43:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101d47:	88 45 f3             	mov    %al,-0xd(%ebp)
        shift &= ~(shiftcode[data] | E0ESC);
c0101d4a:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101d4e:	0f b6 80 40 30 12 c0 	movzbl -0x3fedcfc0(%eax),%eax
c0101d55:	0c 40                	or     $0x40,%al
c0101d57:	0f b6 c0             	movzbl %al,%eax
c0101d5a:	f7 d0                	not    %eax
c0101d5c:	89 c2                	mov    %eax,%edx
c0101d5e:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101d63:	21 d0                	and    %edx,%eax
c0101d65:	a3 48 67 12 c0       	mov    %eax,0xc0126748
        return 0;
c0101d6a:	b8 00 00 00 00       	mov    $0x0,%eax
c0101d6f:	e9 d6 00 00 00       	jmp    c0101e4a <kbd_proc_data+0x187>
    } else if (shift & E0ESC) {
c0101d74:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101d79:	83 e0 40             	and    $0x40,%eax
c0101d7c:	85 c0                	test   %eax,%eax
c0101d7e:	74 11                	je     c0101d91 <kbd_proc_data+0xce>
        // Last character was an E0 escape; or with 0x80
        data |= 0x80;
c0101d80:	80 4d f3 80          	orb    $0x80,-0xd(%ebp)
        shift &= ~E0ESC;
c0101d84:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101d89:	83 e0 bf             	and    $0xffffffbf,%eax
c0101d8c:	a3 48 67 12 c0       	mov    %eax,0xc0126748
    }

    shift |= shiftcode[data];
c0101d91:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101d95:	0f b6 80 40 30 12 c0 	movzbl -0x3fedcfc0(%eax),%eax
c0101d9c:	0f b6 d0             	movzbl %al,%edx
c0101d9f:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101da4:	09 d0                	or     %edx,%eax
c0101da6:	a3 48 67 12 c0       	mov    %eax,0xc0126748
    shift ^= togglecode[data];
c0101dab:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101daf:	0f b6 80 40 31 12 c0 	movzbl -0x3fedcec0(%eax),%eax
c0101db6:	0f b6 d0             	movzbl %al,%edx
c0101db9:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101dbe:	31 d0                	xor    %edx,%eax
c0101dc0:	a3 48 67 12 c0       	mov    %eax,0xc0126748

    c = charcode[shift & (CTL | SHIFT)][data];
c0101dc5:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101dca:	83 e0 03             	and    $0x3,%eax
c0101dcd:	8b 14 85 40 35 12 c0 	mov    -0x3fedcac0(,%eax,4),%edx
c0101dd4:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101dd8:	01 d0                	add    %edx,%eax
c0101dda:	0f b6 00             	movzbl (%eax),%eax
c0101ddd:	0f b6 c0             	movzbl %al,%eax
c0101de0:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (shift & CAPSLOCK) {
c0101de3:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101de8:	83 e0 08             	and    $0x8,%eax
c0101deb:	85 c0                	test   %eax,%eax
c0101ded:	74 22                	je     c0101e11 <kbd_proc_data+0x14e>
        if ('a' <= c && c <= 'z')
c0101def:	83 7d f4 60          	cmpl   $0x60,-0xc(%ebp)
c0101df3:	7e 0c                	jle    c0101e01 <kbd_proc_data+0x13e>
c0101df5:	83 7d f4 7a          	cmpl   $0x7a,-0xc(%ebp)
c0101df9:	7f 06                	jg     c0101e01 <kbd_proc_data+0x13e>
            c += 'A' - 'a';
c0101dfb:	83 6d f4 20          	subl   $0x20,-0xc(%ebp)
c0101dff:	eb 10                	jmp    c0101e11 <kbd_proc_data+0x14e>
        else if ('A' <= c && c <= 'Z')
c0101e01:	83 7d f4 40          	cmpl   $0x40,-0xc(%ebp)
c0101e05:	7e 0a                	jle    c0101e11 <kbd_proc_data+0x14e>
c0101e07:	83 7d f4 5a          	cmpl   $0x5a,-0xc(%ebp)
c0101e0b:	7f 04                	jg     c0101e11 <kbd_proc_data+0x14e>
            c += 'a' - 'A';
c0101e0d:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
    }

    // Process special keys
    // Ctrl-Alt-Del: reboot
    if (!(~shift & (CTL | ALT)) && c == KEY_DEL) {
c0101e11:	a1 48 67 12 c0       	mov    0xc0126748,%eax
c0101e16:	f7 d0                	not    %eax
c0101e18:	83 e0 06             	and    $0x6,%eax
c0101e1b:	85 c0                	test   %eax,%eax
c0101e1d:	75 28                	jne    c0101e47 <kbd_proc_data+0x184>
c0101e1f:	81 7d f4 e9 00 00 00 	cmpl   $0xe9,-0xc(%ebp)
c0101e26:	75 1f                	jne    c0101e47 <kbd_proc_data+0x184>
        cprintf("Rebooting!\n");
c0101e28:	c7 04 24 f9 93 10 c0 	movl   $0xc01093f9,(%esp)
c0101e2f:	e8 a5 e4 ff ff       	call   c01002d9 <cprintf>
c0101e34:	66 c7 45 e8 92 00    	movw   $0x92,-0x18(%ebp)
c0101e3a:	c6 45 e7 03          	movb   $0x3,-0x19(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101e3e:	0f b6 45 e7          	movzbl -0x19(%ebp),%eax
c0101e42:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0101e45:	ee                   	out    %al,(%dx)
}
c0101e46:	90                   	nop
        outb(0x92, 0x3); // courtesy of Chris Frost
    }
    return c;
c0101e47:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101e4a:	c9                   	leave  
c0101e4b:	c3                   	ret    

c0101e4c <kbd_intr>:

/* kbd_intr - try to feed input characters from keyboard */
static void
kbd_intr(void) {
c0101e4c:	f3 0f 1e fb          	endbr32 
c0101e50:	55                   	push   %ebp
c0101e51:	89 e5                	mov    %esp,%ebp
c0101e53:	83 ec 18             	sub    $0x18,%esp
    cons_intr(kbd_proc_data);
c0101e56:	c7 04 24 c3 1c 10 c0 	movl   $0xc0101cc3,(%esp)
c0101e5d:	e8 93 fd ff ff       	call   c0101bf5 <cons_intr>
}
c0101e62:	90                   	nop
c0101e63:	c9                   	leave  
c0101e64:	c3                   	ret    

c0101e65 <kbd_init>:

static void
kbd_init(void) {
c0101e65:	f3 0f 1e fb          	endbr32 
c0101e69:	55                   	push   %ebp
c0101e6a:	89 e5                	mov    %esp,%ebp
c0101e6c:	83 ec 18             	sub    $0x18,%esp
    // drain the kbd buffer
    kbd_intr();
c0101e6f:	e8 d8 ff ff ff       	call   c0101e4c <kbd_intr>
    pic_enable(IRQ_KBD);
c0101e74:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0101e7b:	e8 47 01 00 00       	call   c0101fc7 <pic_enable>
}
c0101e80:	90                   	nop
c0101e81:	c9                   	leave  
c0101e82:	c3                   	ret    

c0101e83 <cons_init>:

/* cons_init - initializes the console devices */
void
cons_init(void) {
c0101e83:	f3 0f 1e fb          	endbr32 
c0101e87:	55                   	push   %ebp
c0101e88:	89 e5                	mov    %esp,%ebp
c0101e8a:	83 ec 18             	sub    $0x18,%esp
    //初始化CGA显示设备
    cga_init();
c0101e8d:	e8 2e f8 ff ff       	call   c01016c0 <cga_init>
    //初始化串行端口
    serial_init();
c0101e92:	e8 13 f9 ff ff       	call   c01017aa <serial_init>
    //初始化键盘
    kbd_init();
c0101e97:	e8 c9 ff ff ff       	call   c0101e65 <kbd_init>
    if (!serial_exists) {
c0101e9c:	a1 28 65 12 c0       	mov    0xc0126528,%eax
c0101ea1:	85 c0                	test   %eax,%eax
c0101ea3:	75 0c                	jne    c0101eb1 <cons_init+0x2e>
        cprintf("serial port does not exist!!\n");
c0101ea5:	c7 04 24 05 94 10 c0 	movl   $0xc0109405,(%esp)
c0101eac:	e8 28 e4 ff ff       	call   c01002d9 <cprintf>
    }
}
c0101eb1:	90                   	nop
c0101eb2:	c9                   	leave  
c0101eb3:	c3                   	ret    

c0101eb4 <cons_putc>:

/* cons_putc - print a single character @c to console devices */
void
cons_putc(int c) {
c0101eb4:	f3 0f 1e fb          	endbr32 
c0101eb8:	55                   	push   %ebp
c0101eb9:	89 e5                	mov    %esp,%ebp
c0101ebb:	83 ec 28             	sub    $0x28,%esp
    bool intr_flag;
    local_intr_save(intr_flag);
c0101ebe:	e8 72 f7 ff ff       	call   c0101635 <__intr_save>
c0101ec3:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        lpt_putc(c);
c0101ec6:	8b 45 08             	mov    0x8(%ebp),%eax
c0101ec9:	89 04 24             	mov    %eax,(%esp)
c0101ecc:	e8 48 fa ff ff       	call   c0101919 <lpt_putc>
        cga_putc(c);
c0101ed1:	8b 45 08             	mov    0x8(%ebp),%eax
c0101ed4:	89 04 24             	mov    %eax,(%esp)
c0101ed7:	e8 81 fa ff ff       	call   c010195d <cga_putc>
        serial_putc(c);
c0101edc:	8b 45 08             	mov    0x8(%ebp),%eax
c0101edf:	89 04 24             	mov    %eax,(%esp)
c0101ee2:	e8 ca fc ff ff       	call   c0101bb1 <serial_putc>
    }
    local_intr_restore(intr_flag);
c0101ee7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0101eea:	89 04 24             	mov    %eax,(%esp)
c0101eed:	e8 6d f7 ff ff       	call   c010165f <__intr_restore>
}
c0101ef2:	90                   	nop
c0101ef3:	c9                   	leave  
c0101ef4:	c3                   	ret    

c0101ef5 <cons_getc>:
/* *
 * cons_getc - return the next input character from console,
 * or 0 if none waiting.
 * */
int
cons_getc(void) {
c0101ef5:	f3 0f 1e fb          	endbr32 
c0101ef9:	55                   	push   %ebp
c0101efa:	89 e5                	mov    %esp,%ebp
c0101efc:	83 ec 28             	sub    $0x28,%esp
    int c = 0;
c0101eff:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    bool intr_flag;
    local_intr_save(intr_flag);
c0101f06:	e8 2a f7 ff ff       	call   c0101635 <__intr_save>
c0101f0b:	89 45 f0             	mov    %eax,-0x10(%ebp)
    {
        // poll for any pending input characters,
        // so that this function works even when interrupts are disabled
        // (e.g., when called from the kernel monitor).
        serial_intr();
c0101f0e:	e8 8e fd ff ff       	call   c0101ca1 <serial_intr>
        kbd_intr();
c0101f13:	e8 34 ff ff ff       	call   c0101e4c <kbd_intr>

        // grab the next character from the input buffer.
        if (cons.rpos != cons.wpos) {
c0101f18:	8b 15 40 67 12 c0    	mov    0xc0126740,%edx
c0101f1e:	a1 44 67 12 c0       	mov    0xc0126744,%eax
c0101f23:	39 c2                	cmp    %eax,%edx
c0101f25:	74 31                	je     c0101f58 <cons_getc+0x63>
            c = cons.buf[cons.rpos ++];
c0101f27:	a1 40 67 12 c0       	mov    0xc0126740,%eax
c0101f2c:	8d 50 01             	lea    0x1(%eax),%edx
c0101f2f:	89 15 40 67 12 c0    	mov    %edx,0xc0126740
c0101f35:	0f b6 80 40 65 12 c0 	movzbl -0x3fed9ac0(%eax),%eax
c0101f3c:	0f b6 c0             	movzbl %al,%eax
c0101f3f:	89 45 f4             	mov    %eax,-0xc(%ebp)
            if (cons.rpos == CONSBUFSIZE) {
c0101f42:	a1 40 67 12 c0       	mov    0xc0126740,%eax
c0101f47:	3d 00 02 00 00       	cmp    $0x200,%eax
c0101f4c:	75 0a                	jne    c0101f58 <cons_getc+0x63>
                cons.rpos = 0;
c0101f4e:	c7 05 40 67 12 c0 00 	movl   $0x0,0xc0126740
c0101f55:	00 00 00 
            }
        }
    }
    local_intr_restore(intr_flag);
c0101f58:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101f5b:	89 04 24             	mov    %eax,(%esp)
c0101f5e:	e8 fc f6 ff ff       	call   c010165f <__intr_restore>
    return c;
c0101f63:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101f66:	c9                   	leave  
c0101f67:	c3                   	ret    

c0101f68 <pic_setmask>:
 * 此函数用于更新内部的IRQ掩码，并在设备初始化后，将掩码值写入到两个级联的可编程中断控制器(PIC)中
 * 
 * @param mask 一个16位的掩码值，用于配置IRQ线的掩码
 */
static void
pic_setmask(uint16_t mask) {
c0101f68:	f3 0f 1e fb          	endbr32 
c0101f6c:	55                   	push   %ebp
c0101f6d:	89 e5                	mov    %esp,%ebp
c0101f6f:	83 ec 14             	sub    $0x14,%esp
c0101f72:	8b 45 08             	mov    0x8(%ebp),%eax
c0101f75:	66 89 45 ec          	mov    %ax,-0x14(%ebp)
    // 更新内部的IRQ掩码
    irq_mask = mask;
c0101f79:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101f7c:	66 a3 50 35 12 c0    	mov    %ax,0xc0123550
    // 仅在设备已初始化的情况下执行后续操作
    if (did_init) {
c0101f82:	a1 4c 67 12 c0       	mov    0xc012674c,%eax
c0101f87:	85 c0                	test   %eax,%eax
c0101f89:	74 39                	je     c0101fc4 <pic_setmask+0x5c>
        // 向主PIC发送低8位的掩码
        outb(IO_PIC1 + 1, mask);
c0101f8b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101f8e:	0f b6 c0             	movzbl %al,%eax
c0101f91:	66 c7 45 fa 21 00    	movw   $0x21,-0x6(%ebp)
c0101f97:	88 45 f9             	mov    %al,-0x7(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101f9a:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c0101f9e:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c0101fa2:	ee                   	out    %al,(%dx)
}
c0101fa3:	90                   	nop
        // 向从PIC发送高8位的掩码
        outb(IO_PIC2 + 1, mask >> 8);
c0101fa4:	0f b7 45 ec          	movzwl -0x14(%ebp),%eax
c0101fa8:	c1 e8 08             	shr    $0x8,%eax
c0101fab:	0f b7 c0             	movzwl %ax,%eax
c0101fae:	0f b6 c0             	movzbl %al,%eax
c0101fb1:	66 c7 45 fe a1 00    	movw   $0xa1,-0x2(%ebp)
c0101fb7:	88 45 fd             	mov    %al,-0x3(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101fba:	0f b6 45 fd          	movzbl -0x3(%ebp),%eax
c0101fbe:	0f b7 55 fe          	movzwl -0x2(%ebp),%edx
c0101fc2:	ee                   	out    %al,(%dx)
}
c0101fc3:	90                   	nop
    }
}
c0101fc4:	90                   	nop
c0101fc5:	c9                   	leave  
c0101fc6:	c3                   	ret    

c0101fc7 <pic_enable>:
 * 此函数通过更新中断掩码寄存器来启用特定的中断源
 * 
 * @param irq 要启用的中断源的编号
 */
void
pic_enable(unsigned int irq) {
c0101fc7:	f3 0f 1e fb          	endbr32 
c0101fcb:	55                   	push   %ebp
c0101fcc:	89 e5                	mov    %esp,%ebp
c0101fce:	83 ec 04             	sub    $0x4,%esp
    // 更新中断掩码，清除对应IRQ的掩码位以启用中断
    pic_setmask(irq_mask & ~(1 << irq));
c0101fd1:	8b 45 08             	mov    0x8(%ebp),%eax
c0101fd4:	ba 01 00 00 00       	mov    $0x1,%edx
c0101fd9:	88 c1                	mov    %al,%cl
c0101fdb:	d3 e2                	shl    %cl,%edx
c0101fdd:	89 d0                	mov    %edx,%eax
c0101fdf:	98                   	cwtl   
c0101fe0:	f7 d0                	not    %eax
c0101fe2:	0f bf d0             	movswl %ax,%edx
c0101fe5:	0f b7 05 50 35 12 c0 	movzwl 0xc0123550,%eax
c0101fec:	98                   	cwtl   
c0101fed:	21 d0                	and    %edx,%eax
c0101fef:	98                   	cwtl   
c0101ff0:	0f b7 c0             	movzwl %ax,%eax
c0101ff3:	89 04 24             	mov    %eax,(%esp)
c0101ff6:	e8 6d ff ff ff       	call   c0101f68 <pic_setmask>
}
c0101ffb:	90                   	nop
c0101ffc:	c9                   	leave  
c0101ffd:	c3                   	ret    

c0101ffe <pic_init>:

/* pic_init - initialize the 8259A interrupt controllers */
// 初始化可编程中断控制器（PIC）
// 此函数配置 PIC 以准备处理系统中的中断
void
pic_init(void) {
c0101ffe:	f3 0f 1e fb          	endbr32 
c0102002:	55                   	push   %ebp
c0102003:	89 e5                	mov    %esp,%ebp
c0102005:	83 ec 44             	sub    $0x44,%esp
    // 标记 PIC 初始化完成
    did_init = 1;
c0102008:	c7 05 4c 67 12 c0 01 	movl   $0x1,0xc012674c
c010200f:	00 00 00 
c0102012:	66 c7 45 ca 21 00    	movw   $0x21,-0x36(%ebp)
c0102018:	c6 45 c9 ff          	movb   $0xff,-0x37(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010201c:	0f b6 45 c9          	movzbl -0x37(%ebp),%eax
c0102020:	0f b7 55 ca          	movzwl -0x36(%ebp),%edx
c0102024:	ee                   	out    %al,(%dx)
}
c0102025:	90                   	nop
c0102026:	66 c7 45 ce a1 00    	movw   $0xa1,-0x32(%ebp)
c010202c:	c6 45 cd ff          	movb   $0xff,-0x33(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102030:	0f b6 45 cd          	movzbl -0x33(%ebp),%eax
c0102034:	0f b7 55 ce          	movzwl -0x32(%ebp),%edx
c0102038:	ee                   	out    %al,(%dx)
}
c0102039:	90                   	nop
c010203a:	66 c7 45 d2 20 00    	movw   $0x20,-0x2e(%ebp)
c0102040:	c6 45 d1 11          	movb   $0x11,-0x2f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102044:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c0102048:	0f b7 55 d2          	movzwl -0x2e(%ebp),%edx
c010204c:	ee                   	out    %al,(%dx)
}
c010204d:	90                   	nop
c010204e:	66 c7 45 d6 21 00    	movw   $0x21,-0x2a(%ebp)
c0102054:	c6 45 d5 20          	movb   $0x20,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102058:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c010205c:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0102060:	ee                   	out    %al,(%dx)
}
c0102061:	90                   	nop
c0102062:	66 c7 45 da 21 00    	movw   $0x21,-0x26(%ebp)
c0102068:	c6 45 d9 04          	movb   $0x4,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010206c:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0102070:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c0102074:	ee                   	out    %al,(%dx)
}
c0102075:	90                   	nop
c0102076:	66 c7 45 de 21 00    	movw   $0x21,-0x22(%ebp)
c010207c:	c6 45 dd 03          	movb   $0x3,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102080:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c0102084:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0102088:	ee                   	out    %al,(%dx)
}
c0102089:	90                   	nop
c010208a:	66 c7 45 e2 a0 00    	movw   $0xa0,-0x1e(%ebp)
c0102090:	c6 45 e1 11          	movb   $0x11,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102094:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0102098:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c010209c:	ee                   	out    %al,(%dx)
}
c010209d:	90                   	nop
c010209e:	66 c7 45 e6 a1 00    	movw   $0xa1,-0x1a(%ebp)
c01020a4:	c6 45 e5 28          	movb   $0x28,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020a8:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c01020ac:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c01020b0:	ee                   	out    %al,(%dx)
}
c01020b1:	90                   	nop
c01020b2:	66 c7 45 ea a1 00    	movw   $0xa1,-0x16(%ebp)
c01020b8:	c6 45 e9 02          	movb   $0x2,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020bc:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c01020c0:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c01020c4:	ee                   	out    %al,(%dx)
}
c01020c5:	90                   	nop
c01020c6:	66 c7 45 ee a1 00    	movw   $0xa1,-0x12(%ebp)
c01020cc:	c6 45 ed 03          	movb   $0x3,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020d0:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c01020d4:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c01020d8:	ee                   	out    %al,(%dx)
}
c01020d9:	90                   	nop
c01020da:	66 c7 45 f2 20 00    	movw   $0x20,-0xe(%ebp)
c01020e0:	c6 45 f1 68          	movb   $0x68,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020e4:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c01020e8:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c01020ec:	ee                   	out    %al,(%dx)
}
c01020ed:	90                   	nop
c01020ee:	66 c7 45 f6 20 00    	movw   $0x20,-0xa(%ebp)
c01020f4:	c6 45 f5 0a          	movb   $0xa,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020f8:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c01020fc:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0102100:	ee                   	out    %al,(%dx)
}
c0102101:	90                   	nop
c0102102:	66 c7 45 fa a0 00    	movw   $0xa0,-0x6(%ebp)
c0102108:	c6 45 f9 68          	movb   $0x68,-0x7(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010210c:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c0102110:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c0102114:	ee                   	out    %al,(%dx)
}
c0102115:	90                   	nop
c0102116:	66 c7 45 fe a0 00    	movw   $0xa0,-0x2(%ebp)
c010211c:	c6 45 fd 0a          	movb   $0xa,-0x3(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102120:	0f b6 45 fd          	movzbl -0x3(%ebp),%eax
c0102124:	0f b7 55 fe          	movzwl -0x2(%ebp),%edx
c0102128:	ee                   	out    %al,(%dx)
}
c0102129:	90                   	nop

    outb(IO_PIC2, 0x68);    // OCW3
    outb(IO_PIC2, 0x0a);    // OCW3
    
    // 如果有自定义的中断掩码，则设置中断掩码
    if (irq_mask != 0xFFFF) {
c010212a:	0f b7 05 50 35 12 c0 	movzwl 0xc0123550,%eax
c0102131:	3d ff ff 00 00       	cmp    $0xffff,%eax
c0102136:	74 0f                	je     c0102147 <pic_init+0x149>
        pic_setmask(irq_mask);
c0102138:	0f b7 05 50 35 12 c0 	movzwl 0xc0123550,%eax
c010213f:	89 04 24             	mov    %eax,(%esp)
c0102142:	e8 21 fe ff ff       	call   c0101f68 <pic_setmask>
    }
}
c0102147:	90                   	nop
c0102148:	c9                   	leave  
c0102149:	c3                   	ret    

c010214a <intr_enable>:
#include <x86.h>
#include <intr.h>

/* intr_enable - enable irq interrupt */
void
intr_enable(void) {
c010214a:	f3 0f 1e fb          	endbr32 
c010214e:	55                   	push   %ebp
c010214f:	89 e5                	mov    %esp,%ebp
    asm volatile ("sti");
c0102151:	fb                   	sti    
}
c0102152:	90                   	nop
    sti();
}
c0102153:	90                   	nop
c0102154:	5d                   	pop    %ebp
c0102155:	c3                   	ret    

c0102156 <intr_disable>:

/* intr_disable - disable irq interrupt */
void
intr_disable(void) {
c0102156:	f3 0f 1e fb          	endbr32 
c010215a:	55                   	push   %ebp
c010215b:	89 e5                	mov    %esp,%ebp
    asm volatile ("cli" ::: "memory");
c010215d:	fa                   	cli    
}
c010215e:	90                   	nop
    cli();
}
c010215f:	90                   	nop
c0102160:	5d                   	pop    %ebp
c0102161:	c3                   	ret    

c0102162 <print_ticks>:
#include <swap.h>
#include <kdebug.h>

#define TICK_NUM 100

static void print_ticks() {
c0102162:	f3 0f 1e fb          	endbr32 
c0102166:	55                   	push   %ebp
c0102167:	89 e5                	mov    %esp,%ebp
c0102169:	83 ec 18             	sub    $0x18,%esp
    cprintf("%d ticks\n",TICK_NUM);
c010216c:	c7 44 24 04 64 00 00 	movl   $0x64,0x4(%esp)
c0102173:	00 
c0102174:	c7 04 24 40 94 10 c0 	movl   $0xc0109440,(%esp)
c010217b:	e8 59 e1 ff ff       	call   c01002d9 <cprintf>
#ifdef DEBUG_GRADE
    cprintf("End of Test.\n");
    panic("EOT: kernel seems ok.");//panic 是一个用于处理内核崩溃的函数，它会打印出错误信息并导致系统停止运行。
#endif
}
c0102180:	90                   	nop
c0102181:	c9                   	leave  
c0102182:	c3                   	ret    

c0102183 <idt_init>:
    sizeof(idt) - 1, (uintptr_t)idt
};

/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void
idt_init(void) {
c0102183:	f3 0f 1e fb          	endbr32 
c0102187:	55                   	push   %ebp
c0102188:	89 e5                	mov    %esp,%ebp
c010218a:	83 ec 10             	sub    $0x10,%esp
      *     Notice: the argument of lidt is idt_pd. try to find it!
      */

    extern uintptr_t __vectors[];//声明了一个外部数组 __vectors，该数组存储中断服务例程（ISR）的地址。
    int i;
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
c010218d:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c0102194:	e9 c4 00 00 00       	jmp    c010225d <idt_init+0xda>
        SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
c0102199:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010219c:	8b 04 85 e0 35 12 c0 	mov    -0x3fedca20(,%eax,4),%eax
c01021a3:	0f b7 d0             	movzwl %ax,%edx
c01021a6:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021a9:	66 89 14 c5 60 67 12 	mov    %dx,-0x3fed98a0(,%eax,8)
c01021b0:	c0 
c01021b1:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021b4:	66 c7 04 c5 62 67 12 	movw   $0x8,-0x3fed989e(,%eax,8)
c01021bb:	c0 08 00 
c01021be:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021c1:	0f b6 14 c5 64 67 12 	movzbl -0x3fed989c(,%eax,8),%edx
c01021c8:	c0 
c01021c9:	80 e2 e0             	and    $0xe0,%dl
c01021cc:	88 14 c5 64 67 12 c0 	mov    %dl,-0x3fed989c(,%eax,8)
c01021d3:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021d6:	0f b6 14 c5 64 67 12 	movzbl -0x3fed989c(,%eax,8),%edx
c01021dd:	c0 
c01021de:	80 e2 1f             	and    $0x1f,%dl
c01021e1:	88 14 c5 64 67 12 c0 	mov    %dl,-0x3fed989c(,%eax,8)
c01021e8:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021eb:	0f b6 14 c5 65 67 12 	movzbl -0x3fed989b(,%eax,8),%edx
c01021f2:	c0 
c01021f3:	80 e2 f0             	and    $0xf0,%dl
c01021f6:	80 ca 0e             	or     $0xe,%dl
c01021f9:	88 14 c5 65 67 12 c0 	mov    %dl,-0x3fed989b(,%eax,8)
c0102200:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102203:	0f b6 14 c5 65 67 12 	movzbl -0x3fed989b(,%eax,8),%edx
c010220a:	c0 
c010220b:	80 e2 ef             	and    $0xef,%dl
c010220e:	88 14 c5 65 67 12 c0 	mov    %dl,-0x3fed989b(,%eax,8)
c0102215:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102218:	0f b6 14 c5 65 67 12 	movzbl -0x3fed989b(,%eax,8),%edx
c010221f:	c0 
c0102220:	80 e2 9f             	and    $0x9f,%dl
c0102223:	88 14 c5 65 67 12 c0 	mov    %dl,-0x3fed989b(,%eax,8)
c010222a:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010222d:	0f b6 14 c5 65 67 12 	movzbl -0x3fed989b(,%eax,8),%edx
c0102234:	c0 
c0102235:	80 ca 80             	or     $0x80,%dl
c0102238:	88 14 c5 65 67 12 c0 	mov    %dl,-0x3fed989b(,%eax,8)
c010223f:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102242:	8b 04 85 e0 35 12 c0 	mov    -0x3fedca20(,%eax,4),%eax
c0102249:	c1 e8 10             	shr    $0x10,%eax
c010224c:	0f b7 d0             	movzwl %ax,%edx
c010224f:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102252:	66 89 14 c5 66 67 12 	mov    %dx,-0x3fed989a(,%eax,8)
c0102259:	c0 
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
c010225a:	ff 45 fc             	incl   -0x4(%ebp)
c010225d:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102260:	3d ff 00 00 00       	cmp    $0xff,%eax
c0102265:	0f 86 2e ff ff ff    	jbe    c0102199 <idt_init+0x16>
    //宏用于配置每个 IDT 条目.0 表示最高特权级（内核级）GD_KTEXT: 指向内核代码段的选择子，确保 ISR 在内核代码段中执行。
	//__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级，表示该中断只能由内核级代码触发。
    // set for switch from user to kernel
    //SETGATE 这行代码特别设置了 T_SWITCH_TOK（一个特定的中断向量，用于用户态到内核态的切换）的 IDT 条目。
    //DPL_USER 表示该中断可以由用户态代码触发
    SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER);
c010226b:	a1 c4 37 12 c0       	mov    0xc01237c4,%eax
c0102270:	0f b7 c0             	movzwl %ax,%eax
c0102273:	66 a3 28 6b 12 c0    	mov    %ax,0xc0126b28
c0102279:	66 c7 05 2a 6b 12 c0 	movw   $0x8,0xc0126b2a
c0102280:	08 00 
c0102282:	0f b6 05 2c 6b 12 c0 	movzbl 0xc0126b2c,%eax
c0102289:	24 e0                	and    $0xe0,%al
c010228b:	a2 2c 6b 12 c0       	mov    %al,0xc0126b2c
c0102290:	0f b6 05 2c 6b 12 c0 	movzbl 0xc0126b2c,%eax
c0102297:	24 1f                	and    $0x1f,%al
c0102299:	a2 2c 6b 12 c0       	mov    %al,0xc0126b2c
c010229e:	0f b6 05 2d 6b 12 c0 	movzbl 0xc0126b2d,%eax
c01022a5:	24 f0                	and    $0xf0,%al
c01022a7:	0c 0e                	or     $0xe,%al
c01022a9:	a2 2d 6b 12 c0       	mov    %al,0xc0126b2d
c01022ae:	0f b6 05 2d 6b 12 c0 	movzbl 0xc0126b2d,%eax
c01022b5:	24 ef                	and    $0xef,%al
c01022b7:	a2 2d 6b 12 c0       	mov    %al,0xc0126b2d
c01022bc:	0f b6 05 2d 6b 12 c0 	movzbl 0xc0126b2d,%eax
c01022c3:	0c 60                	or     $0x60,%al
c01022c5:	a2 2d 6b 12 c0       	mov    %al,0xc0126b2d
c01022ca:	0f b6 05 2d 6b 12 c0 	movzbl 0xc0126b2d,%eax
c01022d1:	0c 80                	or     $0x80,%al
c01022d3:	a2 2d 6b 12 c0       	mov    %al,0xc0126b2d
c01022d8:	a1 c4 37 12 c0       	mov    0xc01237c4,%eax
c01022dd:	c1 e8 10             	shr    $0x10,%eax
c01022e0:	0f b7 c0             	movzwl %ax,%eax
c01022e3:	66 a3 2e 6b 12 c0    	mov    %ax,0xc0126b2e
c01022e9:	c7 45 f8 60 35 12 c0 	movl   $0xc0123560,-0x8(%ebp)
    asm volatile ("lidt (%0)" :: "r" (pd) : "memory");
c01022f0:	8b 45 f8             	mov    -0x8(%ebp),%eax
c01022f3:	0f 01 18             	lidtl  (%eax)
}
c01022f6:	90                   	nop
	// load the IDT
    //使用 lidt 指令将 IDT 描述符加载到 CPU 中
    lidt(&idt_pd);
}
c01022f7:	90                   	nop
c01022f8:	c9                   	leave  
c01022f9:	c3                   	ret    

c01022fa <trapname>:

static const char *
trapname(int trapno) {
c01022fa:	f3 0f 1e fb          	endbr32 
c01022fe:	55                   	push   %ebp
c01022ff:	89 e5                	mov    %esp,%ebp
        "Alignment Check",
        "Machine-Check",
        "SIMD Floating-Point Exception"
    };
    //如果 trapno 小于数组长度，则返回对应的异常名称。
    if (trapno < sizeof(excnames)/sizeof(const char * const)) {
c0102301:	8b 45 08             	mov    0x8(%ebp),%eax
c0102304:	83 f8 13             	cmp    $0x13,%eax
c0102307:	77 0c                	ja     c0102315 <trapname+0x1b>
        return excnames[trapno];
c0102309:	8b 45 08             	mov    0x8(%ebp),%eax
c010230c:	8b 04 85 a0 98 10 c0 	mov    -0x3fef6760(,%eax,4),%eax
c0102313:	eb 18                	jmp    c010232d <trapname+0x33>
    }
    //如果 trapno 在 IRQ_OFFSET 和 IRQ_OFFSET + 16 之间，表示它是一个硬件中断
    if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) {
c0102315:	83 7d 08 1f          	cmpl   $0x1f,0x8(%ebp)
c0102319:	7e 0d                	jle    c0102328 <trapname+0x2e>
c010231b:	83 7d 08 2f          	cmpl   $0x2f,0x8(%ebp)
c010231f:	7f 07                	jg     c0102328 <trapname+0x2e>
        return "Hardware Interrupt";
c0102321:	b8 4a 94 10 c0       	mov    $0xc010944a,%eax
c0102326:	eb 05                	jmp    c010232d <trapname+0x33>
    }
    return "(unknown trap)";
c0102328:	b8 5d 94 10 c0       	mov    $0xc010945d,%eax
}
c010232d:	5d                   	pop    %ebp
c010232e:	c3                   	ret    

c010232f <trap_in_kernel>:

/* trap_in_kernel - test if trap happened in kernel */
bool
trap_in_kernel(struct trapframe *tf) {
c010232f:	f3 0f 1e fb          	endbr32 
c0102333:	55                   	push   %ebp
c0102334:	89 e5                	mov    %esp,%ebp
    return (tf->tf_cs == (uint16_t)KERNEL_CS);
c0102336:	8b 45 08             	mov    0x8(%ebp),%eax
c0102339:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c010233d:	83 f8 08             	cmp    $0x8,%eax
c0102340:	0f 94 c0             	sete   %al
c0102343:	0f b6 c0             	movzbl %al,%eax
    //函数通过检查 tf 中的 tf_cs 字段来判断当前处于哪个特权级,tf_cs 存储了当前代码段选择子的值
    //当 tf->tf_cs 等于 KERNEL_CS 时，表示陷阱发生在内核模式下
}
c0102346:	5d                   	pop    %ebp
c0102347:	c3                   	ret    

c0102348 <print_trapframe>:
    "TF", "IF", "DF", "OF", NULL, NULL, "NT", NULL,
    "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL,
};
//struct trapframe *tf，一个指向 trapframe 结构的指针，包含有关陷阱发生时的 CPU 状态的信息。
void
print_trapframe(struct trapframe *tf) {
c0102348:	f3 0f 1e fb          	endbr32 
c010234c:	55                   	push   %ebp
c010234d:	89 e5                	mov    %esp,%ebp
c010234f:	83 ec 28             	sub    $0x28,%esp
    cprintf("trapframe at %p\n", tf); //打印陷阱框架地址
c0102352:	8b 45 08             	mov    0x8(%ebp),%eax
c0102355:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102359:	c7 04 24 9e 94 10 c0 	movl   $0xc010949e,(%esp)
c0102360:	e8 74 df ff ff       	call   c01002d9 <cprintf>
    print_regs(&tf->tf_regs); //打印寄存器状态
c0102365:	8b 45 08             	mov    0x8(%ebp),%eax
c0102368:	89 04 24             	mov    %eax,(%esp)
c010236b:	e8 8d 01 00 00       	call   c01024fd <print_regs>
    //打印数据段（DS）、扩展段（ES）、文件段（FS）、通用段（GS）的值。
    cprintf("  ds   0x----%04x\n", tf->tf_ds);
c0102370:	8b 45 08             	mov    0x8(%ebp),%eax
c0102373:	0f b7 40 2c          	movzwl 0x2c(%eax),%eax
c0102377:	89 44 24 04          	mov    %eax,0x4(%esp)
c010237b:	c7 04 24 af 94 10 c0 	movl   $0xc01094af,(%esp)
c0102382:	e8 52 df ff ff       	call   c01002d9 <cprintf>
    cprintf("  es   0x----%04x\n", tf->tf_es);
c0102387:	8b 45 08             	mov    0x8(%ebp),%eax
c010238a:	0f b7 40 28          	movzwl 0x28(%eax),%eax
c010238e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102392:	c7 04 24 c2 94 10 c0 	movl   $0xc01094c2,(%esp)
c0102399:	e8 3b df ff ff       	call   c01002d9 <cprintf>
    cprintf("  fs   0x----%04x\n", tf->tf_fs);
c010239e:	8b 45 08             	mov    0x8(%ebp),%eax
c01023a1:	0f b7 40 24          	movzwl 0x24(%eax),%eax
c01023a5:	89 44 24 04          	mov    %eax,0x4(%esp)
c01023a9:	c7 04 24 d5 94 10 c0 	movl   $0xc01094d5,(%esp)
c01023b0:	e8 24 df ff ff       	call   c01002d9 <cprintf>
    cprintf("  gs   0x----%04x\n", tf->tf_gs);
c01023b5:	8b 45 08             	mov    0x8(%ebp),%eax
c01023b8:	0f b7 40 20          	movzwl 0x20(%eax),%eax
c01023bc:	89 44 24 04          	mov    %eax,0x4(%esp)
c01023c0:	c7 04 24 e8 94 10 c0 	movl   $0xc01094e8,(%esp)
c01023c7:	e8 0d df ff ff       	call   c01002d9 <cprintf>
    // 打印陷阱号（trap number）及其对应的名称，通过调用 trapname 函数获取。
    cprintf("  trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
c01023cc:	8b 45 08             	mov    0x8(%ebp),%eax
c01023cf:	8b 40 30             	mov    0x30(%eax),%eax
c01023d2:	89 04 24             	mov    %eax,(%esp)
c01023d5:	e8 20 ff ff ff       	call   c01022fa <trapname>
c01023da:	8b 55 08             	mov    0x8(%ebp),%edx
c01023dd:	8b 52 30             	mov    0x30(%edx),%edx
c01023e0:	89 44 24 08          	mov    %eax,0x8(%esp)
c01023e4:	89 54 24 04          	mov    %edx,0x4(%esp)
c01023e8:	c7 04 24 fb 94 10 c0 	movl   $0xc01094fb,(%esp)
c01023ef:	e8 e5 de ff ff       	call   c01002d9 <cprintf>
    cprintf("  err  0x%08x\n", tf->tf_err);// 如果有错误代码，打印该字段的值。
c01023f4:	8b 45 08             	mov    0x8(%ebp),%eax
c01023f7:	8b 40 34             	mov    0x34(%eax),%eax
c01023fa:	89 44 24 04          	mov    %eax,0x4(%esp)
c01023fe:	c7 04 24 0d 95 10 c0 	movl   $0xc010950d,(%esp)
c0102405:	e8 cf de ff ff       	call   c01002d9 <cprintf>
    cprintf("  eip  0x%08x\n", tf->tf_eip);//打印当前执行的指令指针（EIP），指向出错或中断的指令。
c010240a:	8b 45 08             	mov    0x8(%ebp),%eax
c010240d:	8b 40 38             	mov    0x38(%eax),%eax
c0102410:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102414:	c7 04 24 1c 95 10 c0 	movl   $0xc010951c,(%esp)
c010241b:	e8 b9 de ff ff       	call   c01002d9 <cprintf>
    cprintf("  cs   0x----%04x\n", tf->tf_cs);//打印代码段寄存器（CS）的值。
c0102420:	8b 45 08             	mov    0x8(%ebp),%eax
c0102423:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c0102427:	89 44 24 04          	mov    %eax,0x4(%esp)
c010242b:	c7 04 24 2b 95 10 c0 	movl   $0xc010952b,(%esp)
c0102432:	e8 a2 de ff ff       	call   c01002d9 <cprintf>
    cprintf("  flag 0x%08x ", tf->tf_eflags);// 打印标志寄存器（EFLAGS）的值
c0102437:	8b 45 08             	mov    0x8(%ebp),%eax
c010243a:	8b 40 40             	mov    0x40(%eax),%eax
c010243d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102441:	c7 04 24 3e 95 10 c0 	movl   $0xc010953e,(%esp)
c0102448:	e8 8c de ff ff       	call   c01002d9 <cprintf>
    //使用循环遍历 IA32flags 数组，j 表示当前标志位的位掩码。
    int i, j;
    for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) {
c010244d:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0102454:	c7 45 f0 01 00 00 00 	movl   $0x1,-0x10(%ebp)
c010245b:	eb 3d                	jmp    c010249a <print_trapframe+0x152>
        if ((tf->tf_eflags & j) && IA32flags[i] != NULL) {
c010245d:	8b 45 08             	mov    0x8(%ebp),%eax
c0102460:	8b 50 40             	mov    0x40(%eax),%edx
c0102463:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0102466:	21 d0                	and    %edx,%eax
c0102468:	85 c0                	test   %eax,%eax
c010246a:	74 28                	je     c0102494 <print_trapframe+0x14c>
c010246c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010246f:	8b 04 85 80 35 12 c0 	mov    -0x3fedca80(,%eax,4),%eax
c0102476:	85 c0                	test   %eax,%eax
c0102478:	74 1a                	je     c0102494 <print_trapframe+0x14c>
            cprintf("%s,", IA32flags[i]);
c010247a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010247d:	8b 04 85 80 35 12 c0 	mov    -0x3fedca80(,%eax,4),%eax
c0102484:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102488:	c7 04 24 4d 95 10 c0 	movl   $0xc010954d,(%esp)
c010248f:	e8 45 de ff ff       	call   c01002d9 <cprintf>
    for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) {
c0102494:	ff 45 f4             	incl   -0xc(%ebp)
c0102497:	d1 65 f0             	shll   -0x10(%ebp)
c010249a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010249d:	83 f8 17             	cmp    $0x17,%eax
c01024a0:	76 bb                	jbe    c010245d <print_trapframe+0x115>
        }
    }
    //通过位掩码 FL_IOPL_MASK 获取和打印当前的 I/O 特权级别。
    cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12);
c01024a2:	8b 45 08             	mov    0x8(%ebp),%eax
c01024a5:	8b 40 40             	mov    0x40(%eax),%eax
c01024a8:	c1 e8 0c             	shr    $0xc,%eax
c01024ab:	83 e0 03             	and    $0x3,%eax
c01024ae:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024b2:	c7 04 24 51 95 10 c0 	movl   $0xc0109551,(%esp)
c01024b9:	e8 1b de ff ff       	call   c01002d9 <cprintf>
    //如果陷阱不是在内核中发生的（通过 trap_in_kernel 判断），
    //则打印栈指针（ESP）和栈段（SS）寄存器的值。
    if (!trap_in_kernel(tf)) {
c01024be:	8b 45 08             	mov    0x8(%ebp),%eax
c01024c1:	89 04 24             	mov    %eax,(%esp)
c01024c4:	e8 66 fe ff ff       	call   c010232f <trap_in_kernel>
c01024c9:	85 c0                	test   %eax,%eax
c01024cb:	75 2d                	jne    c01024fa <print_trapframe+0x1b2>
        cprintf("  esp  0x%08x\n", tf->tf_esp);
c01024cd:	8b 45 08             	mov    0x8(%ebp),%eax
c01024d0:	8b 40 44             	mov    0x44(%eax),%eax
c01024d3:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024d7:	c7 04 24 5a 95 10 c0 	movl   $0xc010955a,(%esp)
c01024de:	e8 f6 dd ff ff       	call   c01002d9 <cprintf>
        cprintf("  ss   0x----%04x\n", tf->tf_ss);
c01024e3:	8b 45 08             	mov    0x8(%ebp),%eax
c01024e6:	0f b7 40 48          	movzwl 0x48(%eax),%eax
c01024ea:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024ee:	c7 04 24 69 95 10 c0 	movl   $0xc0109569,(%esp)
c01024f5:	e8 df dd ff ff       	call   c01002d9 <cprintf>
    }
}
c01024fa:	90                   	nop
c01024fb:	c9                   	leave  
c01024fc:	c3                   	ret    

c01024fd <print_regs>:
//定义了一个名为 print_regs 的函数，
//打印出存储在 struct pushregs 结构体中的寄存器值。
void
print_regs(struct pushregs *regs) {
c01024fd:	f3 0f 1e fb          	endbr32 
c0102501:	55                   	push   %ebp
c0102502:	89 e5                	mov    %esp,%ebp
c0102504:	83 ec 18             	sub    $0x18,%esp
    cprintf("  edi  0x%08x\n", regs->reg_edi);
c0102507:	8b 45 08             	mov    0x8(%ebp),%eax
c010250a:	8b 00                	mov    (%eax),%eax
c010250c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102510:	c7 04 24 7c 95 10 c0 	movl   $0xc010957c,(%esp)
c0102517:	e8 bd dd ff ff       	call   c01002d9 <cprintf>
    cprintf("  esi  0x%08x\n", regs->reg_esi);
c010251c:	8b 45 08             	mov    0x8(%ebp),%eax
c010251f:	8b 40 04             	mov    0x4(%eax),%eax
c0102522:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102526:	c7 04 24 8b 95 10 c0 	movl   $0xc010958b,(%esp)
c010252d:	e8 a7 dd ff ff       	call   c01002d9 <cprintf>
    cprintf("  ebp  0x%08x\n", regs->reg_ebp);
c0102532:	8b 45 08             	mov    0x8(%ebp),%eax
c0102535:	8b 40 08             	mov    0x8(%eax),%eax
c0102538:	89 44 24 04          	mov    %eax,0x4(%esp)
c010253c:	c7 04 24 9a 95 10 c0 	movl   $0xc010959a,(%esp)
c0102543:	e8 91 dd ff ff       	call   c01002d9 <cprintf>
    cprintf("  oesp 0x%08x\n", regs->reg_oesp);//打印旧的栈指针（OESP），这个寄存器通常在陷阱或中断发生时用于记录上一个栈指针。
c0102548:	8b 45 08             	mov    0x8(%ebp),%eax
c010254b:	8b 40 0c             	mov    0xc(%eax),%eax
c010254e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102552:	c7 04 24 a9 95 10 c0 	movl   $0xc01095a9,(%esp)
c0102559:	e8 7b dd ff ff       	call   c01002d9 <cprintf>
    cprintf("  ebx  0x%08x\n", regs->reg_ebx);
c010255e:	8b 45 08             	mov    0x8(%ebp),%eax
c0102561:	8b 40 10             	mov    0x10(%eax),%eax
c0102564:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102568:	c7 04 24 b8 95 10 c0 	movl   $0xc01095b8,(%esp)
c010256f:	e8 65 dd ff ff       	call   c01002d9 <cprintf>
    cprintf("  edx  0x%08x\n", regs->reg_edx);
c0102574:	8b 45 08             	mov    0x8(%ebp),%eax
c0102577:	8b 40 14             	mov    0x14(%eax),%eax
c010257a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010257e:	c7 04 24 c7 95 10 c0 	movl   $0xc01095c7,(%esp)
c0102585:	e8 4f dd ff ff       	call   c01002d9 <cprintf>
    cprintf("  ecx  0x%08x\n", regs->reg_ecx);
c010258a:	8b 45 08             	mov    0x8(%ebp),%eax
c010258d:	8b 40 18             	mov    0x18(%eax),%eax
c0102590:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102594:	c7 04 24 d6 95 10 c0 	movl   $0xc01095d6,(%esp)
c010259b:	e8 39 dd ff ff       	call   c01002d9 <cprintf>
    cprintf("  eax  0x%08x\n", regs->reg_eax);
c01025a0:	8b 45 08             	mov    0x8(%ebp),%eax
c01025a3:	8b 40 1c             	mov    0x1c(%eax),%eax
c01025a6:	89 44 24 04          	mov    %eax,0x4(%esp)
c01025aa:	c7 04 24 e5 95 10 c0 	movl   $0xc01095e5,(%esp)
c01025b1:	e8 23 dd ff ff       	call   c01002d9 <cprintf>
}
c01025b6:	90                   	nop
c01025b7:	c9                   	leave  
c01025b8:	c3                   	ret    

c01025b9 <print_pgfault>:
 * 此函数用于输出页面故障的详细信息，包括故障地址、访问类型（读/写）、访问模式（用户/内核）以及故障类型（未找到页面/保护故障）。
 *
 * @param tf 指向 trapframe 结构的指针，包含故障发生时的寄存器状态和错误代码。
 */
static inline void
print_pgfault(struct trapframe *tf) {
c01025b9:	55                   	push   %ebp
c01025ba:	89 e5                	mov    %esp,%ebp
c01025bc:	53                   	push   %ebx
c01025bd:	83 ec 34             	sub    $0x34,%esp
     * bit 2 == 0 表示内核模式，1 表示用户模式
     * */
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
            (tf->tf_err & 4) ? 'U' : 'K',
            (tf->tf_err & 2) ? 'W' : 'R',
            (tf->tf_err & 1) ? "protection fault" : "no page found");
c01025c0:	8b 45 08             	mov    0x8(%ebp),%eax
c01025c3:	8b 40 34             	mov    0x34(%eax),%eax
c01025c6:	83 e0 01             	and    $0x1,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c01025c9:	85 c0                	test   %eax,%eax
c01025cb:	74 07                	je     c01025d4 <print_pgfault+0x1b>
c01025cd:	bb f4 95 10 c0       	mov    $0xc01095f4,%ebx
c01025d2:	eb 05                	jmp    c01025d9 <print_pgfault+0x20>
c01025d4:	bb 05 96 10 c0       	mov    $0xc0109605,%ebx
            (tf->tf_err & 2) ? 'W' : 'R',
c01025d9:	8b 45 08             	mov    0x8(%ebp),%eax
c01025dc:	8b 40 34             	mov    0x34(%eax),%eax
c01025df:	83 e0 02             	and    $0x2,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c01025e2:	85 c0                	test   %eax,%eax
c01025e4:	74 07                	je     c01025ed <print_pgfault+0x34>
c01025e6:	b9 57 00 00 00       	mov    $0x57,%ecx
c01025eb:	eb 05                	jmp    c01025f2 <print_pgfault+0x39>
c01025ed:	b9 52 00 00 00       	mov    $0x52,%ecx
            (tf->tf_err & 4) ? 'U' : 'K',
c01025f2:	8b 45 08             	mov    0x8(%ebp),%eax
c01025f5:	8b 40 34             	mov    0x34(%eax),%eax
c01025f8:	83 e0 04             	and    $0x4,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c01025fb:	85 c0                	test   %eax,%eax
c01025fd:	74 07                	je     c0102606 <print_pgfault+0x4d>
c01025ff:	ba 55 00 00 00       	mov    $0x55,%edx
c0102604:	eb 05                	jmp    c010260b <print_pgfault+0x52>
c0102606:	ba 4b 00 00 00       	mov    $0x4b,%edx
}

static inline uintptr_t
rcr2(void) {
    uintptr_t cr2;
    asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory");
c010260b:	0f 20 d0             	mov    %cr2,%eax
c010260e:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return cr2;
c0102611:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0102614:	89 5c 24 10          	mov    %ebx,0x10(%esp)
c0102618:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c010261c:	89 54 24 08          	mov    %edx,0x8(%esp)
c0102620:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102624:	c7 04 24 14 96 10 c0 	movl   $0xc0109614,(%esp)
c010262b:	e8 a9 dc ff ff       	call   c01002d9 <cprintf>
}
c0102630:	90                   	nop
c0102631:	83 c4 34             	add    $0x34,%esp
c0102634:	5b                   	pop    %ebx
c0102635:	5d                   	pop    %ebp
c0102636:	c3                   	ret    

c0102637 <pgfault_handler>:
 * 
 * @param tf 指向陷阱帧的指针，包含故障发生时的CPU状态信息
 * @return 返回页面故障处理的结果，或者在无法处理时引发系统崩溃
 */
static int
pgfault_handler(struct trapframe *tf) {
c0102637:	f3 0f 1e fb          	endbr32 
c010263b:	55                   	push   %ebp
c010263c:	89 e5                	mov    %esp,%ebp
c010263e:	83 ec 28             	sub    $0x28,%esp
    // 声明一个外部变量，用于检查内存管理结构
    extern struct mm_struct *check_mm_struct;
    // 打印页面故障信息
    print_pgfault(tf);
c0102641:	8b 45 08             	mov    0x8(%ebp),%eax
c0102644:	89 04 24             	mov    %eax,(%esp)
c0102647:	e8 6d ff ff ff       	call   c01025b9 <print_pgfault>
    // 检查是否存在有效的内存管理结构
    if (check_mm_struct != NULL) {
c010264c:	a1 84 70 12 c0       	mov    0xc0127084,%eax
c0102651:	85 c0                	test   %eax,%eax
c0102653:	74 26                	je     c010267b <pgfault_handler+0x44>
    asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory");
c0102655:	0f 20 d0             	mov    %cr2,%eax
c0102658:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return cr2;
c010265b:	8b 4d f4             	mov    -0xc(%ebp),%ecx
        // 如果存在，调用页面故障处理函数
        return do_pgfault(check_mm_struct, tf->tf_err, rcr2());
c010265e:	8b 45 08             	mov    0x8(%ebp),%eax
c0102661:	8b 50 34             	mov    0x34(%eax),%edx
c0102664:	a1 84 70 12 c0       	mov    0xc0127084,%eax
c0102669:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c010266d:	89 54 24 04          	mov    %edx,0x4(%esp)
c0102671:	89 04 24             	mov    %eax,(%esp)
c0102674:	e8 36 3b 00 00       	call   c01061af <do_pgfault>
c0102679:	eb 1c                	jmp    c0102697 <pgfault_handler+0x60>
    }
    // 如果没有有效的内存管理结构，引发系统崩溃
    panic("unhandled page fault.\n");
c010267b:	c7 44 24 08 37 96 10 	movl   $0xc0109637,0x8(%esp)
c0102682:	c0 
c0102683:	c7 44 24 04 d3 00 00 	movl   $0xd3,0x4(%esp)
c010268a:	00 
c010268b:	c7 04 24 4e 96 10 c0 	movl   $0xc010964e,(%esp)
c0102692:	e8 ae dd ff ff       	call   c0100445 <__panic>
}
c0102697:	c9                   	leave  
c0102698:	c3                   	ret    

c0102699 <trap_dispatch>:

struct trapframe switchk2u, *switchu2k;
//定义了一个名为 trap_dispatch 的静态函数，根据发生的陷阱类型进行相应的处理。
// 参数 tf 是指向陷阱帧的指针，包含了关于陷阱发生时的CPU状态信息。
static void
trap_dispatch(struct trapframe *tf) {
c0102699:	f3 0f 1e fb          	endbr32 
c010269d:	55                   	push   %ebp
c010269e:	89 e5                	mov    %esp,%ebp
c01026a0:	57                   	push   %edi
c01026a1:	56                   	push   %esi
c01026a2:	53                   	push   %ebx
c01026a3:	83 ec 2c             	sub    $0x2c,%esp
    char c;

    int ret;
    //通过 switch 语句根据 tf->tf_trapno 的值来分发不同的陷阱处理逻辑。
    switch (tf->tf_trapno) {
c01026a6:	8b 45 08             	mov    0x8(%ebp),%eax
c01026a9:	8b 40 30             	mov    0x30(%eax),%eax
c01026ac:	83 f8 79             	cmp    $0x79,%eax
c01026af:	0f 84 fd 01 00 00    	je     c01028b2 <trap_dispatch+0x219>
c01026b5:	83 f8 79             	cmp    $0x79,%eax
c01026b8:	0f 87 71 02 00 00    	ja     c010292f <trap_dispatch+0x296>
c01026be:	83 f8 2f             	cmp    $0x2f,%eax
c01026c1:	77 1f                	ja     c01026e2 <trap_dispatch+0x49>
c01026c3:	83 f8 0e             	cmp    $0xe,%eax
c01026c6:	0f 82 63 02 00 00    	jb     c010292f <trap_dispatch+0x296>
c01026cc:	83 e8 0e             	sub    $0xe,%eax
c01026cf:	83 f8 21             	cmp    $0x21,%eax
c01026d2:	0f 87 57 02 00 00    	ja     c010292f <trap_dispatch+0x296>
c01026d8:	8b 04 85 b8 96 10 c0 	mov    -0x3fef6948(,%eax,4),%eax
c01026df:	3e ff e0             	notrack jmp *%eax
c01026e2:	83 f8 78             	cmp    $0x78,%eax
c01026e5:	0f 84 e3 00 00 00    	je     c01027ce <trap_dispatch+0x135>
c01026eb:	e9 3f 02 00 00       	jmp    c010292f <trap_dispatch+0x296>
    case T_PGFLT:  //page fault
    // 处理页故障中断
        if ((ret = pgfault_handler(tf)) != 0) {
c01026f0:	8b 45 08             	mov    0x8(%ebp),%eax
c01026f3:	89 04 24             	mov    %eax,(%esp)
c01026f6:	e8 3c ff ff ff       	call   c0102637 <pgfault_handler>
c01026fb:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01026fe:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c0102702:	0f 84 5f 02 00 00    	je     c0102967 <trap_dispatch+0x2ce>
            print_trapframe(tf);
c0102708:	8b 45 08             	mov    0x8(%ebp),%eax
c010270b:	89 04 24             	mov    %eax,(%esp)
c010270e:	e8 35 fc ff ff       	call   c0102348 <print_trapframe>
            panic("handle pgfault failed. %e\n", ret);
c0102713:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0102716:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010271a:	c7 44 24 08 5f 96 10 	movl   $0xc010965f,0x8(%esp)
c0102721:	c0 
c0102722:	c7 44 24 04 e7 00 00 	movl   $0xe7,0x4(%esp)
c0102729:	00 
c010272a:	c7 04 24 4e 96 10 c0 	movl   $0xc010964e,(%esp)
c0102731:	e8 0f dd ff ff       	call   c0100445 <__panic>
        /* handle the timer interrupt */
        /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c
         * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
         * (3) Too Simple? Yes, I think so!
         */
        ticks ++; //记录中断事件
c0102736:	a1 1c 70 12 c0       	mov    0xc012701c,%eax
c010273b:	40                   	inc    %eax
c010273c:	a3 1c 70 12 c0       	mov    %eax,0xc012701c
        if (ticks % TICK_NUM == 0)
c0102741:	8b 0d 1c 70 12 c0    	mov    0xc012701c,%ecx
c0102747:	ba 1f 85 eb 51       	mov    $0x51eb851f,%edx
c010274c:	89 c8                	mov    %ecx,%eax
c010274e:	f7 e2                	mul    %edx
c0102750:	c1 ea 05             	shr    $0x5,%edx
c0102753:	89 d0                	mov    %edx,%eax
c0102755:	c1 e0 02             	shl    $0x2,%eax
c0102758:	01 d0                	add    %edx,%eax
c010275a:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0102761:	01 d0                	add    %edx,%eax
c0102763:	c1 e0 02             	shl    $0x2,%eax
c0102766:	29 c1                	sub    %eax,%ecx
c0102768:	89 ca                	mov    %ecx,%edx
c010276a:	85 d2                	test   %edx,%edx
c010276c:	0f 85 f8 01 00 00    	jne    c010296a <trap_dispatch+0x2d1>
        {
            print_ticks();
c0102772:	e8 eb f9 ff ff       	call   c0102162 <print_ticks>
        }//每经过 TICK_NUM 次周期时，调用 print_ticks() 打印信息。
        break;
c0102777:	e9 ee 01 00 00       	jmp    c010296a <trap_dispatch+0x2d1>
    //处理串口中断，调用 cons_getc() 从串口读取字符并打印。
    case IRQ_OFFSET + IRQ_COM1:
        c = cons_getc();
c010277c:	e8 74 f7 ff ff       	call   c0101ef5 <cons_getc>
c0102781:	88 45 e7             	mov    %al,-0x19(%ebp)
        cprintf("serial [%03d] %c\n", c, c);
c0102784:	0f be 55 e7          	movsbl -0x19(%ebp),%edx
c0102788:	0f be 45 e7          	movsbl -0x19(%ebp),%eax
c010278c:	89 54 24 08          	mov    %edx,0x8(%esp)
c0102790:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102794:	c7 04 24 7a 96 10 c0 	movl   $0xc010967a,(%esp)
c010279b:	e8 39 db ff ff       	call   c01002d9 <cprintf>
        break;
c01027a0:	e9 cc 01 00 00       	jmp    c0102971 <trap_dispatch+0x2d8>
    //处理键盘中断，调用 cons_getc() 读取键盘输入并打印。
    case IRQ_OFFSET + IRQ_KBD:
        c = cons_getc();
c01027a5:	e8 4b f7 ff ff       	call   c0101ef5 <cons_getc>
c01027aa:	88 45 e7             	mov    %al,-0x19(%ebp)
        cprintf("kbd [%03d] %c\n", c, c);
c01027ad:	0f be 55 e7          	movsbl -0x19(%ebp),%edx
c01027b1:	0f be 45 e7          	movsbl -0x19(%ebp),%eax
c01027b5:	89 54 24 08          	mov    %edx,0x8(%esp)
c01027b9:	89 44 24 04          	mov    %eax,0x4(%esp)
c01027bd:	c7 04 24 8c 96 10 c0 	movl   $0xc010968c,(%esp)
c01027c4:	e8 10 db ff ff       	call   c01002d9 <cprintf>
        break;
c01027c9:	e9 a3 01 00 00       	jmp    c0102971 <trap_dispatch+0x2d8>
    //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
    case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。
        if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下
c01027ce:	8b 45 08             	mov    0x8(%ebp),%eax
c01027d1:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c01027d5:	83 f8 1b             	cmp    $0x1b,%eax
c01027d8:	0f 84 8f 01 00 00    	je     c010296d <trap_dispatch+0x2d4>
            switchk2u = *tf; //保存当前陷阱框架
c01027de:	8b 55 08             	mov    0x8(%ebp),%edx
c01027e1:	b8 20 70 12 c0       	mov    $0xc0127020,%eax
c01027e6:	bb 4c 00 00 00       	mov    $0x4c,%ebx
c01027eb:	89 c1                	mov    %eax,%ecx
c01027ed:	83 e1 01             	and    $0x1,%ecx
c01027f0:	85 c9                	test   %ecx,%ecx
c01027f2:	74 0c                	je     c0102800 <trap_dispatch+0x167>
c01027f4:	0f b6 0a             	movzbl (%edx),%ecx
c01027f7:	88 08                	mov    %cl,(%eax)
c01027f9:	8d 40 01             	lea    0x1(%eax),%eax
c01027fc:	8d 52 01             	lea    0x1(%edx),%edx
c01027ff:	4b                   	dec    %ebx
c0102800:	89 c1                	mov    %eax,%ecx
c0102802:	83 e1 02             	and    $0x2,%ecx
c0102805:	85 c9                	test   %ecx,%ecx
c0102807:	74 0f                	je     c0102818 <trap_dispatch+0x17f>
c0102809:	0f b7 0a             	movzwl (%edx),%ecx
c010280c:	66 89 08             	mov    %cx,(%eax)
c010280f:	8d 40 02             	lea    0x2(%eax),%eax
c0102812:	8d 52 02             	lea    0x2(%edx),%edx
c0102815:	83 eb 02             	sub    $0x2,%ebx
c0102818:	89 df                	mov    %ebx,%edi
c010281a:	83 e7 fc             	and    $0xfffffffc,%edi
c010281d:	b9 00 00 00 00       	mov    $0x0,%ecx
c0102822:	8b 34 0a             	mov    (%edx,%ecx,1),%esi
c0102825:	89 34 08             	mov    %esi,(%eax,%ecx,1)
c0102828:	83 c1 04             	add    $0x4,%ecx
c010282b:	39 f9                	cmp    %edi,%ecx
c010282d:	72 f3                	jb     c0102822 <trap_dispatch+0x189>
c010282f:	01 c8                	add    %ecx,%eax
c0102831:	01 ca                	add    %ecx,%edx
c0102833:	b9 00 00 00 00       	mov    $0x0,%ecx
c0102838:	89 de                	mov    %ebx,%esi
c010283a:	83 e6 02             	and    $0x2,%esi
c010283d:	85 f6                	test   %esi,%esi
c010283f:	74 0b                	je     c010284c <trap_dispatch+0x1b3>
c0102841:	0f b7 34 0a          	movzwl (%edx,%ecx,1),%esi
c0102845:	66 89 34 08          	mov    %si,(%eax,%ecx,1)
c0102849:	83 c1 02             	add    $0x2,%ecx
c010284c:	83 e3 01             	and    $0x1,%ebx
c010284f:	85 db                	test   %ebx,%ebx
c0102851:	74 07                	je     c010285a <trap_dispatch+0x1c1>
c0102853:	0f b6 14 0a          	movzbl (%edx,%ecx,1),%edx
c0102857:	88 14 08             	mov    %dl,(%eax,%ecx,1)
            switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器
c010285a:	66 c7 05 5c 70 12 c0 	movw   $0x1b,0xc012705c
c0102861:	1b 00 
            //将数据段和栈段寄存器 都设置为 USER_DS（用户数据段）
            switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS;
c0102863:	66 c7 05 68 70 12 c0 	movw   $0x23,0xc0127068
c010286a:	23 00 
c010286c:	0f b7 05 68 70 12 c0 	movzwl 0xc0127068,%eax
c0102873:	66 a3 48 70 12 c0    	mov    %ax,0xc0127048
c0102879:	0f b7 05 48 70 12 c0 	movzwl 0xc0127048,%eax
c0102880:	66 a3 4c 70 12 c0    	mov    %ax,0xc012704c
            switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8;
c0102886:	8b 45 08             	mov    0x8(%ebp),%eax
c0102889:	83 c0 44             	add    $0x44,%eax
c010288c:	a3 64 70 12 c0       	mov    %eax,0xc0127064
        
            // set eflags, make sure ucore can use io under user mode.
            // if CPL > IOPL, then cpu will generate a general protection.
            switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作
c0102891:	a1 60 70 12 c0       	mov    0xc0127060,%eax
c0102896:	0d 00 30 00 00       	or     $0x3000,%eax
c010289b:	a3 60 70 12 c0       	mov    %eax,0xc0127060
        
            // set temporary stack
            // then iret will jump to the right stack
            *((uint32_t *)tf - 1) = (uint32_t)&switchk2u;
c01028a0:	8b 45 08             	mov    0x8(%ebp),%eax
c01028a3:	83 e8 04             	sub    $0x4,%eax
c01028a6:	ba 20 70 12 c0       	mov    $0xc0127020,%edx
c01028ab:	89 10                	mov    %edx,(%eax)
        }
        break;
c01028ad:	e9 bb 00 00 00       	jmp    c010296d <trap_dispatch+0x2d4>
    case T_SWITCH_TOK://T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。
        if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下
c01028b2:	8b 45 08             	mov    0x8(%ebp),%eax
c01028b5:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c01028b9:	83 f8 08             	cmp    $0x8,%eax
c01028bc:	0f 84 ae 00 00 00    	je     c0102970 <trap_dispatch+0x2d7>
            tf->tf_cs = KERNEL_CS;
c01028c2:	8b 45 08             	mov    0x8(%ebp),%eax
c01028c5:	66 c7 40 3c 08 00    	movw   $0x8,0x3c(%eax)
            tf->tf_ds = tf->tf_es = KERNEL_DS;
c01028cb:	8b 45 08             	mov    0x8(%ebp),%eax
c01028ce:	66 c7 40 28 10 00    	movw   $0x10,0x28(%eax)
c01028d4:	8b 45 08             	mov    0x8(%ebp),%eax
c01028d7:	0f b7 50 28          	movzwl 0x28(%eax),%edx
c01028db:	8b 45 08             	mov    0x8(%ebp),%eax
c01028de:	66 89 50 2c          	mov    %dx,0x2c(%eax)
            //设置内核模式的段寄存器
            tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志
c01028e2:	8b 45 08             	mov    0x8(%ebp),%eax
c01028e5:	8b 40 40             	mov    0x40(%eax),%eax
c01028e8:	25 ff cf ff ff       	and    $0xffffcfff,%eax
c01028ed:	89 c2                	mov    %eax,%edx
c01028ef:	8b 45 08             	mov    0x8(%ebp),%eax
c01028f2:	89 50 40             	mov    %edx,0x40(%eax)
            switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8));
c01028f5:	8b 45 08             	mov    0x8(%ebp),%eax
c01028f8:	8b 40 44             	mov    0x44(%eax),%eax
c01028fb:	83 e8 44             	sub    $0x44,%eax
c01028fe:	a3 6c 70 12 c0       	mov    %eax,0xc012706c
            //使用 memmove 将当前的陷阱框架（除了最后8个字节）复制到新的陷阱框架位置 switchu2k
            memmove(switchu2k, tf, sizeof(struct trapframe) - 8);
c0102903:	a1 6c 70 12 c0       	mov    0xc012706c,%eax
c0102908:	c7 44 24 08 44 00 00 	movl   $0x44,0x8(%esp)
c010290f:	00 
c0102910:	8b 55 08             	mov    0x8(%ebp),%edx
c0102913:	89 54 24 04          	mov    %edx,0x4(%esp)
c0102917:	89 04 24             	mov    %eax,(%esp)
c010291a:	e8 11 5e 00 00       	call   c0108730 <memmove>
            //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置
            *((uint32_t *)tf - 1) = (uint32_t)switchu2k;
c010291f:	8b 15 6c 70 12 c0    	mov    0xc012706c,%edx
c0102925:	8b 45 08             	mov    0x8(%ebp),%eax
c0102928:	83 e8 04             	sub    $0x4,%eax
c010292b:	89 10                	mov    %edx,(%eax)
        }
        break;
c010292d:	eb 41                	jmp    c0102970 <trap_dispatch+0x2d7>
        break;
    default:
        // in kernel, it must be a mistake
        //检查当前陷阱框架的代码段寄存器 tf->tf_cs 的特权级
        //(tf->tf_cs & 3) == 0 检查是否在内核模式中
        if ((tf->tf_cs & 3) == 0) {
c010292f:	8b 45 08             	mov    0x8(%ebp),%eax
c0102932:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c0102936:	83 e0 03             	and    $0x3,%eax
c0102939:	85 c0                	test   %eax,%eax
c010293b:	75 34                	jne    c0102971 <trap_dispatch+0x2d8>
            print_trapframe(tf);
c010293d:	8b 45 08             	mov    0x8(%ebp),%eax
c0102940:	89 04 24             	mov    %eax,(%esp)
c0102943:	e8 00 fa ff ff       	call   c0102348 <print_trapframe>
            panic("unexpected trap in kernel.\n");
c0102948:	c7 44 24 08 9b 96 10 	movl   $0xc010969b,0x8(%esp)
c010294f:	c0 
c0102950:	c7 44 24 04 2f 01 00 	movl   $0x12f,0x4(%esp)
c0102957:	00 
c0102958:	c7 04 24 4e 96 10 c0 	movl   $0xc010964e,(%esp)
c010295f:	e8 e1 da ff ff       	call   c0100445 <__panic>
        break;
c0102964:	90                   	nop
c0102965:	eb 0a                	jmp    c0102971 <trap_dispatch+0x2d8>
        break;
c0102967:	90                   	nop
c0102968:	eb 07                	jmp    c0102971 <trap_dispatch+0x2d8>
        break;
c010296a:	90                   	nop
c010296b:	eb 04                	jmp    c0102971 <trap_dispatch+0x2d8>
        break;
c010296d:	90                   	nop
c010296e:	eb 01                	jmp    c0102971 <trap_dispatch+0x2d8>
        break;
c0102970:	90                   	nop
        }
    }
}
c0102971:	90                   	nop
c0102972:	83 c4 2c             	add    $0x2c,%esp
c0102975:	5b                   	pop    %ebx
c0102976:	5e                   	pop    %esi
c0102977:	5f                   	pop    %edi
c0102978:	5d                   	pop    %ebp
c0102979:	c3                   	ret    

c010297a <trap>:
 * trap - handles or dispatches an exception/interrupt. if and when trap() returns,
 * the code in kern/trap/trapentry.S restores the old CPU state saved in the
 * trapframe and then uses the iret instruction to return from the exception.
 * */
void
trap(struct trapframe *tf) {
c010297a:	f3 0f 1e fb          	endbr32 
c010297e:	55                   	push   %ebp
c010297f:	89 e5                	mov    %esp,%ebp
c0102981:	83 ec 18             	sub    $0x18,%esp
    // dispatch based on what type of trap occurred
    //该行代码调用 trap_dispatch 函数，将陷阱帧传递给它。
    trap_dispatch(tf);
c0102984:	8b 45 08             	mov    0x8(%ebp),%eax
c0102987:	89 04 24             	mov    %eax,(%esp)
c010298a:	e8 0a fd ff ff       	call   c0102699 <trap_dispatch>
}
c010298f:	90                   	nop
c0102990:	c9                   	leave  
c0102991:	c3                   	ret    

c0102992 <vector0>:
# handler
.text
.globl __alltraps
.globl vector0
vector0:
  pushl $0
c0102992:	6a 00                	push   $0x0
  pushl $0
c0102994:	6a 00                	push   $0x0
  jmp __alltraps
c0102996:	e9 69 0a 00 00       	jmp    c0103404 <__alltraps>

c010299b <vector1>:
.globl vector1
vector1:
  pushl $0
c010299b:	6a 00                	push   $0x0
  pushl $1
c010299d:	6a 01                	push   $0x1
  jmp __alltraps
c010299f:	e9 60 0a 00 00       	jmp    c0103404 <__alltraps>

c01029a4 <vector2>:
.globl vector2
vector2:
  pushl $0
c01029a4:	6a 00                	push   $0x0
  pushl $2
c01029a6:	6a 02                	push   $0x2
  jmp __alltraps
c01029a8:	e9 57 0a 00 00       	jmp    c0103404 <__alltraps>

c01029ad <vector3>:
.globl vector3
vector3:
  pushl $0
c01029ad:	6a 00                	push   $0x0
  pushl $3
c01029af:	6a 03                	push   $0x3
  jmp __alltraps
c01029b1:	e9 4e 0a 00 00       	jmp    c0103404 <__alltraps>

c01029b6 <vector4>:
.globl vector4
vector4:
  pushl $0
c01029b6:	6a 00                	push   $0x0
  pushl $4
c01029b8:	6a 04                	push   $0x4
  jmp __alltraps
c01029ba:	e9 45 0a 00 00       	jmp    c0103404 <__alltraps>

c01029bf <vector5>:
.globl vector5
vector5:
  pushl $0
c01029bf:	6a 00                	push   $0x0
  pushl $5
c01029c1:	6a 05                	push   $0x5
  jmp __alltraps
c01029c3:	e9 3c 0a 00 00       	jmp    c0103404 <__alltraps>

c01029c8 <vector6>:
.globl vector6
vector6:
  pushl $0
c01029c8:	6a 00                	push   $0x0
  pushl $6
c01029ca:	6a 06                	push   $0x6
  jmp __alltraps
c01029cc:	e9 33 0a 00 00       	jmp    c0103404 <__alltraps>

c01029d1 <vector7>:
.globl vector7
vector7:
  pushl $0
c01029d1:	6a 00                	push   $0x0
  pushl $7
c01029d3:	6a 07                	push   $0x7
  jmp __alltraps
c01029d5:	e9 2a 0a 00 00       	jmp    c0103404 <__alltraps>

c01029da <vector8>:
.globl vector8
vector8:
  pushl $8
c01029da:	6a 08                	push   $0x8
  jmp __alltraps
c01029dc:	e9 23 0a 00 00       	jmp    c0103404 <__alltraps>

c01029e1 <vector9>:
.globl vector9
vector9:
  pushl $0
c01029e1:	6a 00                	push   $0x0
  pushl $9
c01029e3:	6a 09                	push   $0x9
  jmp __alltraps
c01029e5:	e9 1a 0a 00 00       	jmp    c0103404 <__alltraps>

c01029ea <vector10>:
.globl vector10
vector10:
  pushl $10
c01029ea:	6a 0a                	push   $0xa
  jmp __alltraps
c01029ec:	e9 13 0a 00 00       	jmp    c0103404 <__alltraps>

c01029f1 <vector11>:
.globl vector11
vector11:
  pushl $11
c01029f1:	6a 0b                	push   $0xb
  jmp __alltraps
c01029f3:	e9 0c 0a 00 00       	jmp    c0103404 <__alltraps>

c01029f8 <vector12>:
.globl vector12
vector12:
  pushl $12
c01029f8:	6a 0c                	push   $0xc
  jmp __alltraps
c01029fa:	e9 05 0a 00 00       	jmp    c0103404 <__alltraps>

c01029ff <vector13>:
.globl vector13
vector13:
  pushl $13
c01029ff:	6a 0d                	push   $0xd
  jmp __alltraps
c0102a01:	e9 fe 09 00 00       	jmp    c0103404 <__alltraps>

c0102a06 <vector14>:
.globl vector14
vector14:
  pushl $14
c0102a06:	6a 0e                	push   $0xe
  jmp __alltraps
c0102a08:	e9 f7 09 00 00       	jmp    c0103404 <__alltraps>

c0102a0d <vector15>:
.globl vector15
vector15:
  pushl $0
c0102a0d:	6a 00                	push   $0x0
  pushl $15
c0102a0f:	6a 0f                	push   $0xf
  jmp __alltraps
c0102a11:	e9 ee 09 00 00       	jmp    c0103404 <__alltraps>

c0102a16 <vector16>:
.globl vector16
vector16:
  pushl $0
c0102a16:	6a 00                	push   $0x0
  pushl $16
c0102a18:	6a 10                	push   $0x10
  jmp __alltraps
c0102a1a:	e9 e5 09 00 00       	jmp    c0103404 <__alltraps>

c0102a1f <vector17>:
.globl vector17
vector17:
  pushl $17
c0102a1f:	6a 11                	push   $0x11
  jmp __alltraps
c0102a21:	e9 de 09 00 00       	jmp    c0103404 <__alltraps>

c0102a26 <vector18>:
.globl vector18
vector18:
  pushl $0
c0102a26:	6a 00                	push   $0x0
  pushl $18
c0102a28:	6a 12                	push   $0x12
  jmp __alltraps
c0102a2a:	e9 d5 09 00 00       	jmp    c0103404 <__alltraps>

c0102a2f <vector19>:
.globl vector19
vector19:
  pushl $0
c0102a2f:	6a 00                	push   $0x0
  pushl $19
c0102a31:	6a 13                	push   $0x13
  jmp __alltraps
c0102a33:	e9 cc 09 00 00       	jmp    c0103404 <__alltraps>

c0102a38 <vector20>:
.globl vector20
vector20:
  pushl $0
c0102a38:	6a 00                	push   $0x0
  pushl $20
c0102a3a:	6a 14                	push   $0x14
  jmp __alltraps
c0102a3c:	e9 c3 09 00 00       	jmp    c0103404 <__alltraps>

c0102a41 <vector21>:
.globl vector21
vector21:
  pushl $0
c0102a41:	6a 00                	push   $0x0
  pushl $21
c0102a43:	6a 15                	push   $0x15
  jmp __alltraps
c0102a45:	e9 ba 09 00 00       	jmp    c0103404 <__alltraps>

c0102a4a <vector22>:
.globl vector22
vector22:
  pushl $0
c0102a4a:	6a 00                	push   $0x0
  pushl $22
c0102a4c:	6a 16                	push   $0x16
  jmp __alltraps
c0102a4e:	e9 b1 09 00 00       	jmp    c0103404 <__alltraps>

c0102a53 <vector23>:
.globl vector23
vector23:
  pushl $0
c0102a53:	6a 00                	push   $0x0
  pushl $23
c0102a55:	6a 17                	push   $0x17
  jmp __alltraps
c0102a57:	e9 a8 09 00 00       	jmp    c0103404 <__alltraps>

c0102a5c <vector24>:
.globl vector24
vector24:
  pushl $0
c0102a5c:	6a 00                	push   $0x0
  pushl $24
c0102a5e:	6a 18                	push   $0x18
  jmp __alltraps
c0102a60:	e9 9f 09 00 00       	jmp    c0103404 <__alltraps>

c0102a65 <vector25>:
.globl vector25
vector25:
  pushl $0
c0102a65:	6a 00                	push   $0x0
  pushl $25
c0102a67:	6a 19                	push   $0x19
  jmp __alltraps
c0102a69:	e9 96 09 00 00       	jmp    c0103404 <__alltraps>

c0102a6e <vector26>:
.globl vector26
vector26:
  pushl $0
c0102a6e:	6a 00                	push   $0x0
  pushl $26
c0102a70:	6a 1a                	push   $0x1a
  jmp __alltraps
c0102a72:	e9 8d 09 00 00       	jmp    c0103404 <__alltraps>

c0102a77 <vector27>:
.globl vector27
vector27:
  pushl $0
c0102a77:	6a 00                	push   $0x0
  pushl $27
c0102a79:	6a 1b                	push   $0x1b
  jmp __alltraps
c0102a7b:	e9 84 09 00 00       	jmp    c0103404 <__alltraps>

c0102a80 <vector28>:
.globl vector28
vector28:
  pushl $0
c0102a80:	6a 00                	push   $0x0
  pushl $28
c0102a82:	6a 1c                	push   $0x1c
  jmp __alltraps
c0102a84:	e9 7b 09 00 00       	jmp    c0103404 <__alltraps>

c0102a89 <vector29>:
.globl vector29
vector29:
  pushl $0
c0102a89:	6a 00                	push   $0x0
  pushl $29
c0102a8b:	6a 1d                	push   $0x1d
  jmp __alltraps
c0102a8d:	e9 72 09 00 00       	jmp    c0103404 <__alltraps>

c0102a92 <vector30>:
.globl vector30
vector30:
  pushl $0
c0102a92:	6a 00                	push   $0x0
  pushl $30
c0102a94:	6a 1e                	push   $0x1e
  jmp __alltraps
c0102a96:	e9 69 09 00 00       	jmp    c0103404 <__alltraps>

c0102a9b <vector31>:
.globl vector31
vector31:
  pushl $0
c0102a9b:	6a 00                	push   $0x0
  pushl $31
c0102a9d:	6a 1f                	push   $0x1f
  jmp __alltraps
c0102a9f:	e9 60 09 00 00       	jmp    c0103404 <__alltraps>

c0102aa4 <vector32>:
.globl vector32
vector32:
  pushl $0
c0102aa4:	6a 00                	push   $0x0
  pushl $32
c0102aa6:	6a 20                	push   $0x20
  jmp __alltraps
c0102aa8:	e9 57 09 00 00       	jmp    c0103404 <__alltraps>

c0102aad <vector33>:
.globl vector33
vector33:
  pushl $0
c0102aad:	6a 00                	push   $0x0
  pushl $33
c0102aaf:	6a 21                	push   $0x21
  jmp __alltraps
c0102ab1:	e9 4e 09 00 00       	jmp    c0103404 <__alltraps>

c0102ab6 <vector34>:
.globl vector34
vector34:
  pushl $0
c0102ab6:	6a 00                	push   $0x0
  pushl $34
c0102ab8:	6a 22                	push   $0x22
  jmp __alltraps
c0102aba:	e9 45 09 00 00       	jmp    c0103404 <__alltraps>

c0102abf <vector35>:
.globl vector35
vector35:
  pushl $0
c0102abf:	6a 00                	push   $0x0
  pushl $35
c0102ac1:	6a 23                	push   $0x23
  jmp __alltraps
c0102ac3:	e9 3c 09 00 00       	jmp    c0103404 <__alltraps>

c0102ac8 <vector36>:
.globl vector36
vector36:
  pushl $0
c0102ac8:	6a 00                	push   $0x0
  pushl $36
c0102aca:	6a 24                	push   $0x24
  jmp __alltraps
c0102acc:	e9 33 09 00 00       	jmp    c0103404 <__alltraps>

c0102ad1 <vector37>:
.globl vector37
vector37:
  pushl $0
c0102ad1:	6a 00                	push   $0x0
  pushl $37
c0102ad3:	6a 25                	push   $0x25
  jmp __alltraps
c0102ad5:	e9 2a 09 00 00       	jmp    c0103404 <__alltraps>

c0102ada <vector38>:
.globl vector38
vector38:
  pushl $0
c0102ada:	6a 00                	push   $0x0
  pushl $38
c0102adc:	6a 26                	push   $0x26
  jmp __alltraps
c0102ade:	e9 21 09 00 00       	jmp    c0103404 <__alltraps>

c0102ae3 <vector39>:
.globl vector39
vector39:
  pushl $0
c0102ae3:	6a 00                	push   $0x0
  pushl $39
c0102ae5:	6a 27                	push   $0x27
  jmp __alltraps
c0102ae7:	e9 18 09 00 00       	jmp    c0103404 <__alltraps>

c0102aec <vector40>:
.globl vector40
vector40:
  pushl $0
c0102aec:	6a 00                	push   $0x0
  pushl $40
c0102aee:	6a 28                	push   $0x28
  jmp __alltraps
c0102af0:	e9 0f 09 00 00       	jmp    c0103404 <__alltraps>

c0102af5 <vector41>:
.globl vector41
vector41:
  pushl $0
c0102af5:	6a 00                	push   $0x0
  pushl $41
c0102af7:	6a 29                	push   $0x29
  jmp __alltraps
c0102af9:	e9 06 09 00 00       	jmp    c0103404 <__alltraps>

c0102afe <vector42>:
.globl vector42
vector42:
  pushl $0
c0102afe:	6a 00                	push   $0x0
  pushl $42
c0102b00:	6a 2a                	push   $0x2a
  jmp __alltraps
c0102b02:	e9 fd 08 00 00       	jmp    c0103404 <__alltraps>

c0102b07 <vector43>:
.globl vector43
vector43:
  pushl $0
c0102b07:	6a 00                	push   $0x0
  pushl $43
c0102b09:	6a 2b                	push   $0x2b
  jmp __alltraps
c0102b0b:	e9 f4 08 00 00       	jmp    c0103404 <__alltraps>

c0102b10 <vector44>:
.globl vector44
vector44:
  pushl $0
c0102b10:	6a 00                	push   $0x0
  pushl $44
c0102b12:	6a 2c                	push   $0x2c
  jmp __alltraps
c0102b14:	e9 eb 08 00 00       	jmp    c0103404 <__alltraps>

c0102b19 <vector45>:
.globl vector45
vector45:
  pushl $0
c0102b19:	6a 00                	push   $0x0
  pushl $45
c0102b1b:	6a 2d                	push   $0x2d
  jmp __alltraps
c0102b1d:	e9 e2 08 00 00       	jmp    c0103404 <__alltraps>

c0102b22 <vector46>:
.globl vector46
vector46:
  pushl $0
c0102b22:	6a 00                	push   $0x0
  pushl $46
c0102b24:	6a 2e                	push   $0x2e
  jmp __alltraps
c0102b26:	e9 d9 08 00 00       	jmp    c0103404 <__alltraps>

c0102b2b <vector47>:
.globl vector47
vector47:
  pushl $0
c0102b2b:	6a 00                	push   $0x0
  pushl $47
c0102b2d:	6a 2f                	push   $0x2f
  jmp __alltraps
c0102b2f:	e9 d0 08 00 00       	jmp    c0103404 <__alltraps>

c0102b34 <vector48>:
.globl vector48
vector48:
  pushl $0
c0102b34:	6a 00                	push   $0x0
  pushl $48
c0102b36:	6a 30                	push   $0x30
  jmp __alltraps
c0102b38:	e9 c7 08 00 00       	jmp    c0103404 <__alltraps>

c0102b3d <vector49>:
.globl vector49
vector49:
  pushl $0
c0102b3d:	6a 00                	push   $0x0
  pushl $49
c0102b3f:	6a 31                	push   $0x31
  jmp __alltraps
c0102b41:	e9 be 08 00 00       	jmp    c0103404 <__alltraps>

c0102b46 <vector50>:
.globl vector50
vector50:
  pushl $0
c0102b46:	6a 00                	push   $0x0
  pushl $50
c0102b48:	6a 32                	push   $0x32
  jmp __alltraps
c0102b4a:	e9 b5 08 00 00       	jmp    c0103404 <__alltraps>

c0102b4f <vector51>:
.globl vector51
vector51:
  pushl $0
c0102b4f:	6a 00                	push   $0x0
  pushl $51
c0102b51:	6a 33                	push   $0x33
  jmp __alltraps
c0102b53:	e9 ac 08 00 00       	jmp    c0103404 <__alltraps>

c0102b58 <vector52>:
.globl vector52
vector52:
  pushl $0
c0102b58:	6a 00                	push   $0x0
  pushl $52
c0102b5a:	6a 34                	push   $0x34
  jmp __alltraps
c0102b5c:	e9 a3 08 00 00       	jmp    c0103404 <__alltraps>

c0102b61 <vector53>:
.globl vector53
vector53:
  pushl $0
c0102b61:	6a 00                	push   $0x0
  pushl $53
c0102b63:	6a 35                	push   $0x35
  jmp __alltraps
c0102b65:	e9 9a 08 00 00       	jmp    c0103404 <__alltraps>

c0102b6a <vector54>:
.globl vector54
vector54:
  pushl $0
c0102b6a:	6a 00                	push   $0x0
  pushl $54
c0102b6c:	6a 36                	push   $0x36
  jmp __alltraps
c0102b6e:	e9 91 08 00 00       	jmp    c0103404 <__alltraps>

c0102b73 <vector55>:
.globl vector55
vector55:
  pushl $0
c0102b73:	6a 00                	push   $0x0
  pushl $55
c0102b75:	6a 37                	push   $0x37
  jmp __alltraps
c0102b77:	e9 88 08 00 00       	jmp    c0103404 <__alltraps>

c0102b7c <vector56>:
.globl vector56
vector56:
  pushl $0
c0102b7c:	6a 00                	push   $0x0
  pushl $56
c0102b7e:	6a 38                	push   $0x38
  jmp __alltraps
c0102b80:	e9 7f 08 00 00       	jmp    c0103404 <__alltraps>

c0102b85 <vector57>:
.globl vector57
vector57:
  pushl $0
c0102b85:	6a 00                	push   $0x0
  pushl $57
c0102b87:	6a 39                	push   $0x39
  jmp __alltraps
c0102b89:	e9 76 08 00 00       	jmp    c0103404 <__alltraps>

c0102b8e <vector58>:
.globl vector58
vector58:
  pushl $0
c0102b8e:	6a 00                	push   $0x0
  pushl $58
c0102b90:	6a 3a                	push   $0x3a
  jmp __alltraps
c0102b92:	e9 6d 08 00 00       	jmp    c0103404 <__alltraps>

c0102b97 <vector59>:
.globl vector59
vector59:
  pushl $0
c0102b97:	6a 00                	push   $0x0
  pushl $59
c0102b99:	6a 3b                	push   $0x3b
  jmp __alltraps
c0102b9b:	e9 64 08 00 00       	jmp    c0103404 <__alltraps>

c0102ba0 <vector60>:
.globl vector60
vector60:
  pushl $0
c0102ba0:	6a 00                	push   $0x0
  pushl $60
c0102ba2:	6a 3c                	push   $0x3c
  jmp __alltraps
c0102ba4:	e9 5b 08 00 00       	jmp    c0103404 <__alltraps>

c0102ba9 <vector61>:
.globl vector61
vector61:
  pushl $0
c0102ba9:	6a 00                	push   $0x0
  pushl $61
c0102bab:	6a 3d                	push   $0x3d
  jmp __alltraps
c0102bad:	e9 52 08 00 00       	jmp    c0103404 <__alltraps>

c0102bb2 <vector62>:
.globl vector62
vector62:
  pushl $0
c0102bb2:	6a 00                	push   $0x0
  pushl $62
c0102bb4:	6a 3e                	push   $0x3e
  jmp __alltraps
c0102bb6:	e9 49 08 00 00       	jmp    c0103404 <__alltraps>

c0102bbb <vector63>:
.globl vector63
vector63:
  pushl $0
c0102bbb:	6a 00                	push   $0x0
  pushl $63
c0102bbd:	6a 3f                	push   $0x3f
  jmp __alltraps
c0102bbf:	e9 40 08 00 00       	jmp    c0103404 <__alltraps>

c0102bc4 <vector64>:
.globl vector64
vector64:
  pushl $0
c0102bc4:	6a 00                	push   $0x0
  pushl $64
c0102bc6:	6a 40                	push   $0x40
  jmp __alltraps
c0102bc8:	e9 37 08 00 00       	jmp    c0103404 <__alltraps>

c0102bcd <vector65>:
.globl vector65
vector65:
  pushl $0
c0102bcd:	6a 00                	push   $0x0
  pushl $65
c0102bcf:	6a 41                	push   $0x41
  jmp __alltraps
c0102bd1:	e9 2e 08 00 00       	jmp    c0103404 <__alltraps>

c0102bd6 <vector66>:
.globl vector66
vector66:
  pushl $0
c0102bd6:	6a 00                	push   $0x0
  pushl $66
c0102bd8:	6a 42                	push   $0x42
  jmp __alltraps
c0102bda:	e9 25 08 00 00       	jmp    c0103404 <__alltraps>

c0102bdf <vector67>:
.globl vector67
vector67:
  pushl $0
c0102bdf:	6a 00                	push   $0x0
  pushl $67
c0102be1:	6a 43                	push   $0x43
  jmp __alltraps
c0102be3:	e9 1c 08 00 00       	jmp    c0103404 <__alltraps>

c0102be8 <vector68>:
.globl vector68
vector68:
  pushl $0
c0102be8:	6a 00                	push   $0x0
  pushl $68
c0102bea:	6a 44                	push   $0x44
  jmp __alltraps
c0102bec:	e9 13 08 00 00       	jmp    c0103404 <__alltraps>

c0102bf1 <vector69>:
.globl vector69
vector69:
  pushl $0
c0102bf1:	6a 00                	push   $0x0
  pushl $69
c0102bf3:	6a 45                	push   $0x45
  jmp __alltraps
c0102bf5:	e9 0a 08 00 00       	jmp    c0103404 <__alltraps>

c0102bfa <vector70>:
.globl vector70
vector70:
  pushl $0
c0102bfa:	6a 00                	push   $0x0
  pushl $70
c0102bfc:	6a 46                	push   $0x46
  jmp __alltraps
c0102bfe:	e9 01 08 00 00       	jmp    c0103404 <__alltraps>

c0102c03 <vector71>:
.globl vector71
vector71:
  pushl $0
c0102c03:	6a 00                	push   $0x0
  pushl $71
c0102c05:	6a 47                	push   $0x47
  jmp __alltraps
c0102c07:	e9 f8 07 00 00       	jmp    c0103404 <__alltraps>

c0102c0c <vector72>:
.globl vector72
vector72:
  pushl $0
c0102c0c:	6a 00                	push   $0x0
  pushl $72
c0102c0e:	6a 48                	push   $0x48
  jmp __alltraps
c0102c10:	e9 ef 07 00 00       	jmp    c0103404 <__alltraps>

c0102c15 <vector73>:
.globl vector73
vector73:
  pushl $0
c0102c15:	6a 00                	push   $0x0
  pushl $73
c0102c17:	6a 49                	push   $0x49
  jmp __alltraps
c0102c19:	e9 e6 07 00 00       	jmp    c0103404 <__alltraps>

c0102c1e <vector74>:
.globl vector74
vector74:
  pushl $0
c0102c1e:	6a 00                	push   $0x0
  pushl $74
c0102c20:	6a 4a                	push   $0x4a
  jmp __alltraps
c0102c22:	e9 dd 07 00 00       	jmp    c0103404 <__alltraps>

c0102c27 <vector75>:
.globl vector75
vector75:
  pushl $0
c0102c27:	6a 00                	push   $0x0
  pushl $75
c0102c29:	6a 4b                	push   $0x4b
  jmp __alltraps
c0102c2b:	e9 d4 07 00 00       	jmp    c0103404 <__alltraps>

c0102c30 <vector76>:
.globl vector76
vector76:
  pushl $0
c0102c30:	6a 00                	push   $0x0
  pushl $76
c0102c32:	6a 4c                	push   $0x4c
  jmp __alltraps
c0102c34:	e9 cb 07 00 00       	jmp    c0103404 <__alltraps>

c0102c39 <vector77>:
.globl vector77
vector77:
  pushl $0
c0102c39:	6a 00                	push   $0x0
  pushl $77
c0102c3b:	6a 4d                	push   $0x4d
  jmp __alltraps
c0102c3d:	e9 c2 07 00 00       	jmp    c0103404 <__alltraps>

c0102c42 <vector78>:
.globl vector78
vector78:
  pushl $0
c0102c42:	6a 00                	push   $0x0
  pushl $78
c0102c44:	6a 4e                	push   $0x4e
  jmp __alltraps
c0102c46:	e9 b9 07 00 00       	jmp    c0103404 <__alltraps>

c0102c4b <vector79>:
.globl vector79
vector79:
  pushl $0
c0102c4b:	6a 00                	push   $0x0
  pushl $79
c0102c4d:	6a 4f                	push   $0x4f
  jmp __alltraps
c0102c4f:	e9 b0 07 00 00       	jmp    c0103404 <__alltraps>

c0102c54 <vector80>:
.globl vector80
vector80:
  pushl $0
c0102c54:	6a 00                	push   $0x0
  pushl $80
c0102c56:	6a 50                	push   $0x50
  jmp __alltraps
c0102c58:	e9 a7 07 00 00       	jmp    c0103404 <__alltraps>

c0102c5d <vector81>:
.globl vector81
vector81:
  pushl $0
c0102c5d:	6a 00                	push   $0x0
  pushl $81
c0102c5f:	6a 51                	push   $0x51
  jmp __alltraps
c0102c61:	e9 9e 07 00 00       	jmp    c0103404 <__alltraps>

c0102c66 <vector82>:
.globl vector82
vector82:
  pushl $0
c0102c66:	6a 00                	push   $0x0
  pushl $82
c0102c68:	6a 52                	push   $0x52
  jmp __alltraps
c0102c6a:	e9 95 07 00 00       	jmp    c0103404 <__alltraps>

c0102c6f <vector83>:
.globl vector83
vector83:
  pushl $0
c0102c6f:	6a 00                	push   $0x0
  pushl $83
c0102c71:	6a 53                	push   $0x53
  jmp __alltraps
c0102c73:	e9 8c 07 00 00       	jmp    c0103404 <__alltraps>

c0102c78 <vector84>:
.globl vector84
vector84:
  pushl $0
c0102c78:	6a 00                	push   $0x0
  pushl $84
c0102c7a:	6a 54                	push   $0x54
  jmp __alltraps
c0102c7c:	e9 83 07 00 00       	jmp    c0103404 <__alltraps>

c0102c81 <vector85>:
.globl vector85
vector85:
  pushl $0
c0102c81:	6a 00                	push   $0x0
  pushl $85
c0102c83:	6a 55                	push   $0x55
  jmp __alltraps
c0102c85:	e9 7a 07 00 00       	jmp    c0103404 <__alltraps>

c0102c8a <vector86>:
.globl vector86
vector86:
  pushl $0
c0102c8a:	6a 00                	push   $0x0
  pushl $86
c0102c8c:	6a 56                	push   $0x56
  jmp __alltraps
c0102c8e:	e9 71 07 00 00       	jmp    c0103404 <__alltraps>

c0102c93 <vector87>:
.globl vector87
vector87:
  pushl $0
c0102c93:	6a 00                	push   $0x0
  pushl $87
c0102c95:	6a 57                	push   $0x57
  jmp __alltraps
c0102c97:	e9 68 07 00 00       	jmp    c0103404 <__alltraps>

c0102c9c <vector88>:
.globl vector88
vector88:
  pushl $0
c0102c9c:	6a 00                	push   $0x0
  pushl $88
c0102c9e:	6a 58                	push   $0x58
  jmp __alltraps
c0102ca0:	e9 5f 07 00 00       	jmp    c0103404 <__alltraps>

c0102ca5 <vector89>:
.globl vector89
vector89:
  pushl $0
c0102ca5:	6a 00                	push   $0x0
  pushl $89
c0102ca7:	6a 59                	push   $0x59
  jmp __alltraps
c0102ca9:	e9 56 07 00 00       	jmp    c0103404 <__alltraps>

c0102cae <vector90>:
.globl vector90
vector90:
  pushl $0
c0102cae:	6a 00                	push   $0x0
  pushl $90
c0102cb0:	6a 5a                	push   $0x5a
  jmp __alltraps
c0102cb2:	e9 4d 07 00 00       	jmp    c0103404 <__alltraps>

c0102cb7 <vector91>:
.globl vector91
vector91:
  pushl $0
c0102cb7:	6a 00                	push   $0x0
  pushl $91
c0102cb9:	6a 5b                	push   $0x5b
  jmp __alltraps
c0102cbb:	e9 44 07 00 00       	jmp    c0103404 <__alltraps>

c0102cc0 <vector92>:
.globl vector92
vector92:
  pushl $0
c0102cc0:	6a 00                	push   $0x0
  pushl $92
c0102cc2:	6a 5c                	push   $0x5c
  jmp __alltraps
c0102cc4:	e9 3b 07 00 00       	jmp    c0103404 <__alltraps>

c0102cc9 <vector93>:
.globl vector93
vector93:
  pushl $0
c0102cc9:	6a 00                	push   $0x0
  pushl $93
c0102ccb:	6a 5d                	push   $0x5d
  jmp __alltraps
c0102ccd:	e9 32 07 00 00       	jmp    c0103404 <__alltraps>

c0102cd2 <vector94>:
.globl vector94
vector94:
  pushl $0
c0102cd2:	6a 00                	push   $0x0
  pushl $94
c0102cd4:	6a 5e                	push   $0x5e
  jmp __alltraps
c0102cd6:	e9 29 07 00 00       	jmp    c0103404 <__alltraps>

c0102cdb <vector95>:
.globl vector95
vector95:
  pushl $0
c0102cdb:	6a 00                	push   $0x0
  pushl $95
c0102cdd:	6a 5f                	push   $0x5f
  jmp __alltraps
c0102cdf:	e9 20 07 00 00       	jmp    c0103404 <__alltraps>

c0102ce4 <vector96>:
.globl vector96
vector96:
  pushl $0
c0102ce4:	6a 00                	push   $0x0
  pushl $96
c0102ce6:	6a 60                	push   $0x60
  jmp __alltraps
c0102ce8:	e9 17 07 00 00       	jmp    c0103404 <__alltraps>

c0102ced <vector97>:
.globl vector97
vector97:
  pushl $0
c0102ced:	6a 00                	push   $0x0
  pushl $97
c0102cef:	6a 61                	push   $0x61
  jmp __alltraps
c0102cf1:	e9 0e 07 00 00       	jmp    c0103404 <__alltraps>

c0102cf6 <vector98>:
.globl vector98
vector98:
  pushl $0
c0102cf6:	6a 00                	push   $0x0
  pushl $98
c0102cf8:	6a 62                	push   $0x62
  jmp __alltraps
c0102cfa:	e9 05 07 00 00       	jmp    c0103404 <__alltraps>

c0102cff <vector99>:
.globl vector99
vector99:
  pushl $0
c0102cff:	6a 00                	push   $0x0
  pushl $99
c0102d01:	6a 63                	push   $0x63
  jmp __alltraps
c0102d03:	e9 fc 06 00 00       	jmp    c0103404 <__alltraps>

c0102d08 <vector100>:
.globl vector100
vector100:
  pushl $0
c0102d08:	6a 00                	push   $0x0
  pushl $100
c0102d0a:	6a 64                	push   $0x64
  jmp __alltraps
c0102d0c:	e9 f3 06 00 00       	jmp    c0103404 <__alltraps>

c0102d11 <vector101>:
.globl vector101
vector101:
  pushl $0
c0102d11:	6a 00                	push   $0x0
  pushl $101
c0102d13:	6a 65                	push   $0x65
  jmp __alltraps
c0102d15:	e9 ea 06 00 00       	jmp    c0103404 <__alltraps>

c0102d1a <vector102>:
.globl vector102
vector102:
  pushl $0
c0102d1a:	6a 00                	push   $0x0
  pushl $102
c0102d1c:	6a 66                	push   $0x66
  jmp __alltraps
c0102d1e:	e9 e1 06 00 00       	jmp    c0103404 <__alltraps>

c0102d23 <vector103>:
.globl vector103
vector103:
  pushl $0
c0102d23:	6a 00                	push   $0x0
  pushl $103
c0102d25:	6a 67                	push   $0x67
  jmp __alltraps
c0102d27:	e9 d8 06 00 00       	jmp    c0103404 <__alltraps>

c0102d2c <vector104>:
.globl vector104
vector104:
  pushl $0
c0102d2c:	6a 00                	push   $0x0
  pushl $104
c0102d2e:	6a 68                	push   $0x68
  jmp __alltraps
c0102d30:	e9 cf 06 00 00       	jmp    c0103404 <__alltraps>

c0102d35 <vector105>:
.globl vector105
vector105:
  pushl $0
c0102d35:	6a 00                	push   $0x0
  pushl $105
c0102d37:	6a 69                	push   $0x69
  jmp __alltraps
c0102d39:	e9 c6 06 00 00       	jmp    c0103404 <__alltraps>

c0102d3e <vector106>:
.globl vector106
vector106:
  pushl $0
c0102d3e:	6a 00                	push   $0x0
  pushl $106
c0102d40:	6a 6a                	push   $0x6a
  jmp __alltraps
c0102d42:	e9 bd 06 00 00       	jmp    c0103404 <__alltraps>

c0102d47 <vector107>:
.globl vector107
vector107:
  pushl $0
c0102d47:	6a 00                	push   $0x0
  pushl $107
c0102d49:	6a 6b                	push   $0x6b
  jmp __alltraps
c0102d4b:	e9 b4 06 00 00       	jmp    c0103404 <__alltraps>

c0102d50 <vector108>:
.globl vector108
vector108:
  pushl $0
c0102d50:	6a 00                	push   $0x0
  pushl $108
c0102d52:	6a 6c                	push   $0x6c
  jmp __alltraps
c0102d54:	e9 ab 06 00 00       	jmp    c0103404 <__alltraps>

c0102d59 <vector109>:
.globl vector109
vector109:
  pushl $0
c0102d59:	6a 00                	push   $0x0
  pushl $109
c0102d5b:	6a 6d                	push   $0x6d
  jmp __alltraps
c0102d5d:	e9 a2 06 00 00       	jmp    c0103404 <__alltraps>

c0102d62 <vector110>:
.globl vector110
vector110:
  pushl $0
c0102d62:	6a 00                	push   $0x0
  pushl $110
c0102d64:	6a 6e                	push   $0x6e
  jmp __alltraps
c0102d66:	e9 99 06 00 00       	jmp    c0103404 <__alltraps>

c0102d6b <vector111>:
.globl vector111
vector111:
  pushl $0
c0102d6b:	6a 00                	push   $0x0
  pushl $111
c0102d6d:	6a 6f                	push   $0x6f
  jmp __alltraps
c0102d6f:	e9 90 06 00 00       	jmp    c0103404 <__alltraps>

c0102d74 <vector112>:
.globl vector112
vector112:
  pushl $0
c0102d74:	6a 00                	push   $0x0
  pushl $112
c0102d76:	6a 70                	push   $0x70
  jmp __alltraps
c0102d78:	e9 87 06 00 00       	jmp    c0103404 <__alltraps>

c0102d7d <vector113>:
.globl vector113
vector113:
  pushl $0
c0102d7d:	6a 00                	push   $0x0
  pushl $113
c0102d7f:	6a 71                	push   $0x71
  jmp __alltraps
c0102d81:	e9 7e 06 00 00       	jmp    c0103404 <__alltraps>

c0102d86 <vector114>:
.globl vector114
vector114:
  pushl $0
c0102d86:	6a 00                	push   $0x0
  pushl $114
c0102d88:	6a 72                	push   $0x72
  jmp __alltraps
c0102d8a:	e9 75 06 00 00       	jmp    c0103404 <__alltraps>

c0102d8f <vector115>:
.globl vector115
vector115:
  pushl $0
c0102d8f:	6a 00                	push   $0x0
  pushl $115
c0102d91:	6a 73                	push   $0x73
  jmp __alltraps
c0102d93:	e9 6c 06 00 00       	jmp    c0103404 <__alltraps>

c0102d98 <vector116>:
.globl vector116
vector116:
  pushl $0
c0102d98:	6a 00                	push   $0x0
  pushl $116
c0102d9a:	6a 74                	push   $0x74
  jmp __alltraps
c0102d9c:	e9 63 06 00 00       	jmp    c0103404 <__alltraps>

c0102da1 <vector117>:
.globl vector117
vector117:
  pushl $0
c0102da1:	6a 00                	push   $0x0
  pushl $117
c0102da3:	6a 75                	push   $0x75
  jmp __alltraps
c0102da5:	e9 5a 06 00 00       	jmp    c0103404 <__alltraps>

c0102daa <vector118>:
.globl vector118
vector118:
  pushl $0
c0102daa:	6a 00                	push   $0x0
  pushl $118
c0102dac:	6a 76                	push   $0x76
  jmp __alltraps
c0102dae:	e9 51 06 00 00       	jmp    c0103404 <__alltraps>

c0102db3 <vector119>:
.globl vector119
vector119:
  pushl $0
c0102db3:	6a 00                	push   $0x0
  pushl $119
c0102db5:	6a 77                	push   $0x77
  jmp __alltraps
c0102db7:	e9 48 06 00 00       	jmp    c0103404 <__alltraps>

c0102dbc <vector120>:
.globl vector120
vector120:
  pushl $0
c0102dbc:	6a 00                	push   $0x0
  pushl $120
c0102dbe:	6a 78                	push   $0x78
  jmp __alltraps
c0102dc0:	e9 3f 06 00 00       	jmp    c0103404 <__alltraps>

c0102dc5 <vector121>:
.globl vector121
vector121:
  pushl $0
c0102dc5:	6a 00                	push   $0x0
  pushl $121
c0102dc7:	6a 79                	push   $0x79
  jmp __alltraps
c0102dc9:	e9 36 06 00 00       	jmp    c0103404 <__alltraps>

c0102dce <vector122>:
.globl vector122
vector122:
  pushl $0
c0102dce:	6a 00                	push   $0x0
  pushl $122
c0102dd0:	6a 7a                	push   $0x7a
  jmp __alltraps
c0102dd2:	e9 2d 06 00 00       	jmp    c0103404 <__alltraps>

c0102dd7 <vector123>:
.globl vector123
vector123:
  pushl $0
c0102dd7:	6a 00                	push   $0x0
  pushl $123
c0102dd9:	6a 7b                	push   $0x7b
  jmp __alltraps
c0102ddb:	e9 24 06 00 00       	jmp    c0103404 <__alltraps>

c0102de0 <vector124>:
.globl vector124
vector124:
  pushl $0
c0102de0:	6a 00                	push   $0x0
  pushl $124
c0102de2:	6a 7c                	push   $0x7c
  jmp __alltraps
c0102de4:	e9 1b 06 00 00       	jmp    c0103404 <__alltraps>

c0102de9 <vector125>:
.globl vector125
vector125:
  pushl $0
c0102de9:	6a 00                	push   $0x0
  pushl $125
c0102deb:	6a 7d                	push   $0x7d
  jmp __alltraps
c0102ded:	e9 12 06 00 00       	jmp    c0103404 <__alltraps>

c0102df2 <vector126>:
.globl vector126
vector126:
  pushl $0
c0102df2:	6a 00                	push   $0x0
  pushl $126
c0102df4:	6a 7e                	push   $0x7e
  jmp __alltraps
c0102df6:	e9 09 06 00 00       	jmp    c0103404 <__alltraps>

c0102dfb <vector127>:
.globl vector127
vector127:
  pushl $0
c0102dfb:	6a 00                	push   $0x0
  pushl $127
c0102dfd:	6a 7f                	push   $0x7f
  jmp __alltraps
c0102dff:	e9 00 06 00 00       	jmp    c0103404 <__alltraps>

c0102e04 <vector128>:
.globl vector128
vector128:
  pushl $0
c0102e04:	6a 00                	push   $0x0
  pushl $128
c0102e06:	68 80 00 00 00       	push   $0x80
  jmp __alltraps
c0102e0b:	e9 f4 05 00 00       	jmp    c0103404 <__alltraps>

c0102e10 <vector129>:
.globl vector129
vector129:
  pushl $0
c0102e10:	6a 00                	push   $0x0
  pushl $129
c0102e12:	68 81 00 00 00       	push   $0x81
  jmp __alltraps
c0102e17:	e9 e8 05 00 00       	jmp    c0103404 <__alltraps>

c0102e1c <vector130>:
.globl vector130
vector130:
  pushl $0
c0102e1c:	6a 00                	push   $0x0
  pushl $130
c0102e1e:	68 82 00 00 00       	push   $0x82
  jmp __alltraps
c0102e23:	e9 dc 05 00 00       	jmp    c0103404 <__alltraps>

c0102e28 <vector131>:
.globl vector131
vector131:
  pushl $0
c0102e28:	6a 00                	push   $0x0
  pushl $131
c0102e2a:	68 83 00 00 00       	push   $0x83
  jmp __alltraps
c0102e2f:	e9 d0 05 00 00       	jmp    c0103404 <__alltraps>

c0102e34 <vector132>:
.globl vector132
vector132:
  pushl $0
c0102e34:	6a 00                	push   $0x0
  pushl $132
c0102e36:	68 84 00 00 00       	push   $0x84
  jmp __alltraps
c0102e3b:	e9 c4 05 00 00       	jmp    c0103404 <__alltraps>

c0102e40 <vector133>:
.globl vector133
vector133:
  pushl $0
c0102e40:	6a 00                	push   $0x0
  pushl $133
c0102e42:	68 85 00 00 00       	push   $0x85
  jmp __alltraps
c0102e47:	e9 b8 05 00 00       	jmp    c0103404 <__alltraps>

c0102e4c <vector134>:
.globl vector134
vector134:
  pushl $0
c0102e4c:	6a 00                	push   $0x0
  pushl $134
c0102e4e:	68 86 00 00 00       	push   $0x86
  jmp __alltraps
c0102e53:	e9 ac 05 00 00       	jmp    c0103404 <__alltraps>

c0102e58 <vector135>:
.globl vector135
vector135:
  pushl $0
c0102e58:	6a 00                	push   $0x0
  pushl $135
c0102e5a:	68 87 00 00 00       	push   $0x87
  jmp __alltraps
c0102e5f:	e9 a0 05 00 00       	jmp    c0103404 <__alltraps>

c0102e64 <vector136>:
.globl vector136
vector136:
  pushl $0
c0102e64:	6a 00                	push   $0x0
  pushl $136
c0102e66:	68 88 00 00 00       	push   $0x88
  jmp __alltraps
c0102e6b:	e9 94 05 00 00       	jmp    c0103404 <__alltraps>

c0102e70 <vector137>:
.globl vector137
vector137:
  pushl $0
c0102e70:	6a 00                	push   $0x0
  pushl $137
c0102e72:	68 89 00 00 00       	push   $0x89
  jmp __alltraps
c0102e77:	e9 88 05 00 00       	jmp    c0103404 <__alltraps>

c0102e7c <vector138>:
.globl vector138
vector138:
  pushl $0
c0102e7c:	6a 00                	push   $0x0
  pushl $138
c0102e7e:	68 8a 00 00 00       	push   $0x8a
  jmp __alltraps
c0102e83:	e9 7c 05 00 00       	jmp    c0103404 <__alltraps>

c0102e88 <vector139>:
.globl vector139
vector139:
  pushl $0
c0102e88:	6a 00                	push   $0x0
  pushl $139
c0102e8a:	68 8b 00 00 00       	push   $0x8b
  jmp __alltraps
c0102e8f:	e9 70 05 00 00       	jmp    c0103404 <__alltraps>

c0102e94 <vector140>:
.globl vector140
vector140:
  pushl $0
c0102e94:	6a 00                	push   $0x0
  pushl $140
c0102e96:	68 8c 00 00 00       	push   $0x8c
  jmp __alltraps
c0102e9b:	e9 64 05 00 00       	jmp    c0103404 <__alltraps>

c0102ea0 <vector141>:
.globl vector141
vector141:
  pushl $0
c0102ea0:	6a 00                	push   $0x0
  pushl $141
c0102ea2:	68 8d 00 00 00       	push   $0x8d
  jmp __alltraps
c0102ea7:	e9 58 05 00 00       	jmp    c0103404 <__alltraps>

c0102eac <vector142>:
.globl vector142
vector142:
  pushl $0
c0102eac:	6a 00                	push   $0x0
  pushl $142
c0102eae:	68 8e 00 00 00       	push   $0x8e
  jmp __alltraps
c0102eb3:	e9 4c 05 00 00       	jmp    c0103404 <__alltraps>

c0102eb8 <vector143>:
.globl vector143
vector143:
  pushl $0
c0102eb8:	6a 00                	push   $0x0
  pushl $143
c0102eba:	68 8f 00 00 00       	push   $0x8f
  jmp __alltraps
c0102ebf:	e9 40 05 00 00       	jmp    c0103404 <__alltraps>

c0102ec4 <vector144>:
.globl vector144
vector144:
  pushl $0
c0102ec4:	6a 00                	push   $0x0
  pushl $144
c0102ec6:	68 90 00 00 00       	push   $0x90
  jmp __alltraps
c0102ecb:	e9 34 05 00 00       	jmp    c0103404 <__alltraps>

c0102ed0 <vector145>:
.globl vector145
vector145:
  pushl $0
c0102ed0:	6a 00                	push   $0x0
  pushl $145
c0102ed2:	68 91 00 00 00       	push   $0x91
  jmp __alltraps
c0102ed7:	e9 28 05 00 00       	jmp    c0103404 <__alltraps>

c0102edc <vector146>:
.globl vector146
vector146:
  pushl $0
c0102edc:	6a 00                	push   $0x0
  pushl $146
c0102ede:	68 92 00 00 00       	push   $0x92
  jmp __alltraps
c0102ee3:	e9 1c 05 00 00       	jmp    c0103404 <__alltraps>

c0102ee8 <vector147>:
.globl vector147
vector147:
  pushl $0
c0102ee8:	6a 00                	push   $0x0
  pushl $147
c0102eea:	68 93 00 00 00       	push   $0x93
  jmp __alltraps
c0102eef:	e9 10 05 00 00       	jmp    c0103404 <__alltraps>

c0102ef4 <vector148>:
.globl vector148
vector148:
  pushl $0
c0102ef4:	6a 00                	push   $0x0
  pushl $148
c0102ef6:	68 94 00 00 00       	push   $0x94
  jmp __alltraps
c0102efb:	e9 04 05 00 00       	jmp    c0103404 <__alltraps>

c0102f00 <vector149>:
.globl vector149
vector149:
  pushl $0
c0102f00:	6a 00                	push   $0x0
  pushl $149
c0102f02:	68 95 00 00 00       	push   $0x95
  jmp __alltraps
c0102f07:	e9 f8 04 00 00       	jmp    c0103404 <__alltraps>

c0102f0c <vector150>:
.globl vector150
vector150:
  pushl $0
c0102f0c:	6a 00                	push   $0x0
  pushl $150
c0102f0e:	68 96 00 00 00       	push   $0x96
  jmp __alltraps
c0102f13:	e9 ec 04 00 00       	jmp    c0103404 <__alltraps>

c0102f18 <vector151>:
.globl vector151
vector151:
  pushl $0
c0102f18:	6a 00                	push   $0x0
  pushl $151
c0102f1a:	68 97 00 00 00       	push   $0x97
  jmp __alltraps
c0102f1f:	e9 e0 04 00 00       	jmp    c0103404 <__alltraps>

c0102f24 <vector152>:
.globl vector152
vector152:
  pushl $0
c0102f24:	6a 00                	push   $0x0
  pushl $152
c0102f26:	68 98 00 00 00       	push   $0x98
  jmp __alltraps
c0102f2b:	e9 d4 04 00 00       	jmp    c0103404 <__alltraps>

c0102f30 <vector153>:
.globl vector153
vector153:
  pushl $0
c0102f30:	6a 00                	push   $0x0
  pushl $153
c0102f32:	68 99 00 00 00       	push   $0x99
  jmp __alltraps
c0102f37:	e9 c8 04 00 00       	jmp    c0103404 <__alltraps>

c0102f3c <vector154>:
.globl vector154
vector154:
  pushl $0
c0102f3c:	6a 00                	push   $0x0
  pushl $154
c0102f3e:	68 9a 00 00 00       	push   $0x9a
  jmp __alltraps
c0102f43:	e9 bc 04 00 00       	jmp    c0103404 <__alltraps>

c0102f48 <vector155>:
.globl vector155
vector155:
  pushl $0
c0102f48:	6a 00                	push   $0x0
  pushl $155
c0102f4a:	68 9b 00 00 00       	push   $0x9b
  jmp __alltraps
c0102f4f:	e9 b0 04 00 00       	jmp    c0103404 <__alltraps>

c0102f54 <vector156>:
.globl vector156
vector156:
  pushl $0
c0102f54:	6a 00                	push   $0x0
  pushl $156
c0102f56:	68 9c 00 00 00       	push   $0x9c
  jmp __alltraps
c0102f5b:	e9 a4 04 00 00       	jmp    c0103404 <__alltraps>

c0102f60 <vector157>:
.globl vector157
vector157:
  pushl $0
c0102f60:	6a 00                	push   $0x0
  pushl $157
c0102f62:	68 9d 00 00 00       	push   $0x9d
  jmp __alltraps
c0102f67:	e9 98 04 00 00       	jmp    c0103404 <__alltraps>

c0102f6c <vector158>:
.globl vector158
vector158:
  pushl $0
c0102f6c:	6a 00                	push   $0x0
  pushl $158
c0102f6e:	68 9e 00 00 00       	push   $0x9e
  jmp __alltraps
c0102f73:	e9 8c 04 00 00       	jmp    c0103404 <__alltraps>

c0102f78 <vector159>:
.globl vector159
vector159:
  pushl $0
c0102f78:	6a 00                	push   $0x0
  pushl $159
c0102f7a:	68 9f 00 00 00       	push   $0x9f
  jmp __alltraps
c0102f7f:	e9 80 04 00 00       	jmp    c0103404 <__alltraps>

c0102f84 <vector160>:
.globl vector160
vector160:
  pushl $0
c0102f84:	6a 00                	push   $0x0
  pushl $160
c0102f86:	68 a0 00 00 00       	push   $0xa0
  jmp __alltraps
c0102f8b:	e9 74 04 00 00       	jmp    c0103404 <__alltraps>

c0102f90 <vector161>:
.globl vector161
vector161:
  pushl $0
c0102f90:	6a 00                	push   $0x0
  pushl $161
c0102f92:	68 a1 00 00 00       	push   $0xa1
  jmp __alltraps
c0102f97:	e9 68 04 00 00       	jmp    c0103404 <__alltraps>

c0102f9c <vector162>:
.globl vector162
vector162:
  pushl $0
c0102f9c:	6a 00                	push   $0x0
  pushl $162
c0102f9e:	68 a2 00 00 00       	push   $0xa2
  jmp __alltraps
c0102fa3:	e9 5c 04 00 00       	jmp    c0103404 <__alltraps>

c0102fa8 <vector163>:
.globl vector163
vector163:
  pushl $0
c0102fa8:	6a 00                	push   $0x0
  pushl $163
c0102faa:	68 a3 00 00 00       	push   $0xa3
  jmp __alltraps
c0102faf:	e9 50 04 00 00       	jmp    c0103404 <__alltraps>

c0102fb4 <vector164>:
.globl vector164
vector164:
  pushl $0
c0102fb4:	6a 00                	push   $0x0
  pushl $164
c0102fb6:	68 a4 00 00 00       	push   $0xa4
  jmp __alltraps
c0102fbb:	e9 44 04 00 00       	jmp    c0103404 <__alltraps>

c0102fc0 <vector165>:
.globl vector165
vector165:
  pushl $0
c0102fc0:	6a 00                	push   $0x0
  pushl $165
c0102fc2:	68 a5 00 00 00       	push   $0xa5
  jmp __alltraps
c0102fc7:	e9 38 04 00 00       	jmp    c0103404 <__alltraps>

c0102fcc <vector166>:
.globl vector166
vector166:
  pushl $0
c0102fcc:	6a 00                	push   $0x0
  pushl $166
c0102fce:	68 a6 00 00 00       	push   $0xa6
  jmp __alltraps
c0102fd3:	e9 2c 04 00 00       	jmp    c0103404 <__alltraps>

c0102fd8 <vector167>:
.globl vector167
vector167:
  pushl $0
c0102fd8:	6a 00                	push   $0x0
  pushl $167
c0102fda:	68 a7 00 00 00       	push   $0xa7
  jmp __alltraps
c0102fdf:	e9 20 04 00 00       	jmp    c0103404 <__alltraps>

c0102fe4 <vector168>:
.globl vector168
vector168:
  pushl $0
c0102fe4:	6a 00                	push   $0x0
  pushl $168
c0102fe6:	68 a8 00 00 00       	push   $0xa8
  jmp __alltraps
c0102feb:	e9 14 04 00 00       	jmp    c0103404 <__alltraps>

c0102ff0 <vector169>:
.globl vector169
vector169:
  pushl $0
c0102ff0:	6a 00                	push   $0x0
  pushl $169
c0102ff2:	68 a9 00 00 00       	push   $0xa9
  jmp __alltraps
c0102ff7:	e9 08 04 00 00       	jmp    c0103404 <__alltraps>

c0102ffc <vector170>:
.globl vector170
vector170:
  pushl $0
c0102ffc:	6a 00                	push   $0x0
  pushl $170
c0102ffe:	68 aa 00 00 00       	push   $0xaa
  jmp __alltraps
c0103003:	e9 fc 03 00 00       	jmp    c0103404 <__alltraps>

c0103008 <vector171>:
.globl vector171
vector171:
  pushl $0
c0103008:	6a 00                	push   $0x0
  pushl $171
c010300a:	68 ab 00 00 00       	push   $0xab
  jmp __alltraps
c010300f:	e9 f0 03 00 00       	jmp    c0103404 <__alltraps>

c0103014 <vector172>:
.globl vector172
vector172:
  pushl $0
c0103014:	6a 00                	push   $0x0
  pushl $172
c0103016:	68 ac 00 00 00       	push   $0xac
  jmp __alltraps
c010301b:	e9 e4 03 00 00       	jmp    c0103404 <__alltraps>

c0103020 <vector173>:
.globl vector173
vector173:
  pushl $0
c0103020:	6a 00                	push   $0x0
  pushl $173
c0103022:	68 ad 00 00 00       	push   $0xad
  jmp __alltraps
c0103027:	e9 d8 03 00 00       	jmp    c0103404 <__alltraps>

c010302c <vector174>:
.globl vector174
vector174:
  pushl $0
c010302c:	6a 00                	push   $0x0
  pushl $174
c010302e:	68 ae 00 00 00       	push   $0xae
  jmp __alltraps
c0103033:	e9 cc 03 00 00       	jmp    c0103404 <__alltraps>

c0103038 <vector175>:
.globl vector175
vector175:
  pushl $0
c0103038:	6a 00                	push   $0x0
  pushl $175
c010303a:	68 af 00 00 00       	push   $0xaf
  jmp __alltraps
c010303f:	e9 c0 03 00 00       	jmp    c0103404 <__alltraps>

c0103044 <vector176>:
.globl vector176
vector176:
  pushl $0
c0103044:	6a 00                	push   $0x0
  pushl $176
c0103046:	68 b0 00 00 00       	push   $0xb0
  jmp __alltraps
c010304b:	e9 b4 03 00 00       	jmp    c0103404 <__alltraps>

c0103050 <vector177>:
.globl vector177
vector177:
  pushl $0
c0103050:	6a 00                	push   $0x0
  pushl $177
c0103052:	68 b1 00 00 00       	push   $0xb1
  jmp __alltraps
c0103057:	e9 a8 03 00 00       	jmp    c0103404 <__alltraps>

c010305c <vector178>:
.globl vector178
vector178:
  pushl $0
c010305c:	6a 00                	push   $0x0
  pushl $178
c010305e:	68 b2 00 00 00       	push   $0xb2
  jmp __alltraps
c0103063:	e9 9c 03 00 00       	jmp    c0103404 <__alltraps>

c0103068 <vector179>:
.globl vector179
vector179:
  pushl $0
c0103068:	6a 00                	push   $0x0
  pushl $179
c010306a:	68 b3 00 00 00       	push   $0xb3
  jmp __alltraps
c010306f:	e9 90 03 00 00       	jmp    c0103404 <__alltraps>

c0103074 <vector180>:
.globl vector180
vector180:
  pushl $0
c0103074:	6a 00                	push   $0x0
  pushl $180
c0103076:	68 b4 00 00 00       	push   $0xb4
  jmp __alltraps
c010307b:	e9 84 03 00 00       	jmp    c0103404 <__alltraps>

c0103080 <vector181>:
.globl vector181
vector181:
  pushl $0
c0103080:	6a 00                	push   $0x0
  pushl $181
c0103082:	68 b5 00 00 00       	push   $0xb5
  jmp __alltraps
c0103087:	e9 78 03 00 00       	jmp    c0103404 <__alltraps>

c010308c <vector182>:
.globl vector182
vector182:
  pushl $0
c010308c:	6a 00                	push   $0x0
  pushl $182
c010308e:	68 b6 00 00 00       	push   $0xb6
  jmp __alltraps
c0103093:	e9 6c 03 00 00       	jmp    c0103404 <__alltraps>

c0103098 <vector183>:
.globl vector183
vector183:
  pushl $0
c0103098:	6a 00                	push   $0x0
  pushl $183
c010309a:	68 b7 00 00 00       	push   $0xb7
  jmp __alltraps
c010309f:	e9 60 03 00 00       	jmp    c0103404 <__alltraps>

c01030a4 <vector184>:
.globl vector184
vector184:
  pushl $0
c01030a4:	6a 00                	push   $0x0
  pushl $184
c01030a6:	68 b8 00 00 00       	push   $0xb8
  jmp __alltraps
c01030ab:	e9 54 03 00 00       	jmp    c0103404 <__alltraps>

c01030b0 <vector185>:
.globl vector185
vector185:
  pushl $0
c01030b0:	6a 00                	push   $0x0
  pushl $185
c01030b2:	68 b9 00 00 00       	push   $0xb9
  jmp __alltraps
c01030b7:	e9 48 03 00 00       	jmp    c0103404 <__alltraps>

c01030bc <vector186>:
.globl vector186
vector186:
  pushl $0
c01030bc:	6a 00                	push   $0x0
  pushl $186
c01030be:	68 ba 00 00 00       	push   $0xba
  jmp __alltraps
c01030c3:	e9 3c 03 00 00       	jmp    c0103404 <__alltraps>

c01030c8 <vector187>:
.globl vector187
vector187:
  pushl $0
c01030c8:	6a 00                	push   $0x0
  pushl $187
c01030ca:	68 bb 00 00 00       	push   $0xbb
  jmp __alltraps
c01030cf:	e9 30 03 00 00       	jmp    c0103404 <__alltraps>

c01030d4 <vector188>:
.globl vector188
vector188:
  pushl $0
c01030d4:	6a 00                	push   $0x0
  pushl $188
c01030d6:	68 bc 00 00 00       	push   $0xbc
  jmp __alltraps
c01030db:	e9 24 03 00 00       	jmp    c0103404 <__alltraps>

c01030e0 <vector189>:
.globl vector189
vector189:
  pushl $0
c01030e0:	6a 00                	push   $0x0
  pushl $189
c01030e2:	68 bd 00 00 00       	push   $0xbd
  jmp __alltraps
c01030e7:	e9 18 03 00 00       	jmp    c0103404 <__alltraps>

c01030ec <vector190>:
.globl vector190
vector190:
  pushl $0
c01030ec:	6a 00                	push   $0x0
  pushl $190
c01030ee:	68 be 00 00 00       	push   $0xbe
  jmp __alltraps
c01030f3:	e9 0c 03 00 00       	jmp    c0103404 <__alltraps>

c01030f8 <vector191>:
.globl vector191
vector191:
  pushl $0
c01030f8:	6a 00                	push   $0x0
  pushl $191
c01030fa:	68 bf 00 00 00       	push   $0xbf
  jmp __alltraps
c01030ff:	e9 00 03 00 00       	jmp    c0103404 <__alltraps>

c0103104 <vector192>:
.globl vector192
vector192:
  pushl $0
c0103104:	6a 00                	push   $0x0
  pushl $192
c0103106:	68 c0 00 00 00       	push   $0xc0
  jmp __alltraps
c010310b:	e9 f4 02 00 00       	jmp    c0103404 <__alltraps>

c0103110 <vector193>:
.globl vector193
vector193:
  pushl $0
c0103110:	6a 00                	push   $0x0
  pushl $193
c0103112:	68 c1 00 00 00       	push   $0xc1
  jmp __alltraps
c0103117:	e9 e8 02 00 00       	jmp    c0103404 <__alltraps>

c010311c <vector194>:
.globl vector194
vector194:
  pushl $0
c010311c:	6a 00                	push   $0x0
  pushl $194
c010311e:	68 c2 00 00 00       	push   $0xc2
  jmp __alltraps
c0103123:	e9 dc 02 00 00       	jmp    c0103404 <__alltraps>

c0103128 <vector195>:
.globl vector195
vector195:
  pushl $0
c0103128:	6a 00                	push   $0x0
  pushl $195
c010312a:	68 c3 00 00 00       	push   $0xc3
  jmp __alltraps
c010312f:	e9 d0 02 00 00       	jmp    c0103404 <__alltraps>

c0103134 <vector196>:
.globl vector196
vector196:
  pushl $0
c0103134:	6a 00                	push   $0x0
  pushl $196
c0103136:	68 c4 00 00 00       	push   $0xc4
  jmp __alltraps
c010313b:	e9 c4 02 00 00       	jmp    c0103404 <__alltraps>

c0103140 <vector197>:
.globl vector197
vector197:
  pushl $0
c0103140:	6a 00                	push   $0x0
  pushl $197
c0103142:	68 c5 00 00 00       	push   $0xc5
  jmp __alltraps
c0103147:	e9 b8 02 00 00       	jmp    c0103404 <__alltraps>

c010314c <vector198>:
.globl vector198
vector198:
  pushl $0
c010314c:	6a 00                	push   $0x0
  pushl $198
c010314e:	68 c6 00 00 00       	push   $0xc6
  jmp __alltraps
c0103153:	e9 ac 02 00 00       	jmp    c0103404 <__alltraps>

c0103158 <vector199>:
.globl vector199
vector199:
  pushl $0
c0103158:	6a 00                	push   $0x0
  pushl $199
c010315a:	68 c7 00 00 00       	push   $0xc7
  jmp __alltraps
c010315f:	e9 a0 02 00 00       	jmp    c0103404 <__alltraps>

c0103164 <vector200>:
.globl vector200
vector200:
  pushl $0
c0103164:	6a 00                	push   $0x0
  pushl $200
c0103166:	68 c8 00 00 00       	push   $0xc8
  jmp __alltraps
c010316b:	e9 94 02 00 00       	jmp    c0103404 <__alltraps>

c0103170 <vector201>:
.globl vector201
vector201:
  pushl $0
c0103170:	6a 00                	push   $0x0
  pushl $201
c0103172:	68 c9 00 00 00       	push   $0xc9
  jmp __alltraps
c0103177:	e9 88 02 00 00       	jmp    c0103404 <__alltraps>

c010317c <vector202>:
.globl vector202
vector202:
  pushl $0
c010317c:	6a 00                	push   $0x0
  pushl $202
c010317e:	68 ca 00 00 00       	push   $0xca
  jmp __alltraps
c0103183:	e9 7c 02 00 00       	jmp    c0103404 <__alltraps>

c0103188 <vector203>:
.globl vector203
vector203:
  pushl $0
c0103188:	6a 00                	push   $0x0
  pushl $203
c010318a:	68 cb 00 00 00       	push   $0xcb
  jmp __alltraps
c010318f:	e9 70 02 00 00       	jmp    c0103404 <__alltraps>

c0103194 <vector204>:
.globl vector204
vector204:
  pushl $0
c0103194:	6a 00                	push   $0x0
  pushl $204
c0103196:	68 cc 00 00 00       	push   $0xcc
  jmp __alltraps
c010319b:	e9 64 02 00 00       	jmp    c0103404 <__alltraps>

c01031a0 <vector205>:
.globl vector205
vector205:
  pushl $0
c01031a0:	6a 00                	push   $0x0
  pushl $205
c01031a2:	68 cd 00 00 00       	push   $0xcd
  jmp __alltraps
c01031a7:	e9 58 02 00 00       	jmp    c0103404 <__alltraps>

c01031ac <vector206>:
.globl vector206
vector206:
  pushl $0
c01031ac:	6a 00                	push   $0x0
  pushl $206
c01031ae:	68 ce 00 00 00       	push   $0xce
  jmp __alltraps
c01031b3:	e9 4c 02 00 00       	jmp    c0103404 <__alltraps>

c01031b8 <vector207>:
.globl vector207
vector207:
  pushl $0
c01031b8:	6a 00                	push   $0x0
  pushl $207
c01031ba:	68 cf 00 00 00       	push   $0xcf
  jmp __alltraps
c01031bf:	e9 40 02 00 00       	jmp    c0103404 <__alltraps>

c01031c4 <vector208>:
.globl vector208
vector208:
  pushl $0
c01031c4:	6a 00                	push   $0x0
  pushl $208
c01031c6:	68 d0 00 00 00       	push   $0xd0
  jmp __alltraps
c01031cb:	e9 34 02 00 00       	jmp    c0103404 <__alltraps>

c01031d0 <vector209>:
.globl vector209
vector209:
  pushl $0
c01031d0:	6a 00                	push   $0x0
  pushl $209
c01031d2:	68 d1 00 00 00       	push   $0xd1
  jmp __alltraps
c01031d7:	e9 28 02 00 00       	jmp    c0103404 <__alltraps>

c01031dc <vector210>:
.globl vector210
vector210:
  pushl $0
c01031dc:	6a 00                	push   $0x0
  pushl $210
c01031de:	68 d2 00 00 00       	push   $0xd2
  jmp __alltraps
c01031e3:	e9 1c 02 00 00       	jmp    c0103404 <__alltraps>

c01031e8 <vector211>:
.globl vector211
vector211:
  pushl $0
c01031e8:	6a 00                	push   $0x0
  pushl $211
c01031ea:	68 d3 00 00 00       	push   $0xd3
  jmp __alltraps
c01031ef:	e9 10 02 00 00       	jmp    c0103404 <__alltraps>

c01031f4 <vector212>:
.globl vector212
vector212:
  pushl $0
c01031f4:	6a 00                	push   $0x0
  pushl $212
c01031f6:	68 d4 00 00 00       	push   $0xd4
  jmp __alltraps
c01031fb:	e9 04 02 00 00       	jmp    c0103404 <__alltraps>

c0103200 <vector213>:
.globl vector213
vector213:
  pushl $0
c0103200:	6a 00                	push   $0x0
  pushl $213
c0103202:	68 d5 00 00 00       	push   $0xd5
  jmp __alltraps
c0103207:	e9 f8 01 00 00       	jmp    c0103404 <__alltraps>

c010320c <vector214>:
.globl vector214
vector214:
  pushl $0
c010320c:	6a 00                	push   $0x0
  pushl $214
c010320e:	68 d6 00 00 00       	push   $0xd6
  jmp __alltraps
c0103213:	e9 ec 01 00 00       	jmp    c0103404 <__alltraps>

c0103218 <vector215>:
.globl vector215
vector215:
  pushl $0
c0103218:	6a 00                	push   $0x0
  pushl $215
c010321a:	68 d7 00 00 00       	push   $0xd7
  jmp __alltraps
c010321f:	e9 e0 01 00 00       	jmp    c0103404 <__alltraps>

c0103224 <vector216>:
.globl vector216
vector216:
  pushl $0
c0103224:	6a 00                	push   $0x0
  pushl $216
c0103226:	68 d8 00 00 00       	push   $0xd8
  jmp __alltraps
c010322b:	e9 d4 01 00 00       	jmp    c0103404 <__alltraps>

c0103230 <vector217>:
.globl vector217
vector217:
  pushl $0
c0103230:	6a 00                	push   $0x0
  pushl $217
c0103232:	68 d9 00 00 00       	push   $0xd9
  jmp __alltraps
c0103237:	e9 c8 01 00 00       	jmp    c0103404 <__alltraps>

c010323c <vector218>:
.globl vector218
vector218:
  pushl $0
c010323c:	6a 00                	push   $0x0
  pushl $218
c010323e:	68 da 00 00 00       	push   $0xda
  jmp __alltraps
c0103243:	e9 bc 01 00 00       	jmp    c0103404 <__alltraps>

c0103248 <vector219>:
.globl vector219
vector219:
  pushl $0
c0103248:	6a 00                	push   $0x0
  pushl $219
c010324a:	68 db 00 00 00       	push   $0xdb
  jmp __alltraps
c010324f:	e9 b0 01 00 00       	jmp    c0103404 <__alltraps>

c0103254 <vector220>:
.globl vector220
vector220:
  pushl $0
c0103254:	6a 00                	push   $0x0
  pushl $220
c0103256:	68 dc 00 00 00       	push   $0xdc
  jmp __alltraps
c010325b:	e9 a4 01 00 00       	jmp    c0103404 <__alltraps>

c0103260 <vector221>:
.globl vector221
vector221:
  pushl $0
c0103260:	6a 00                	push   $0x0
  pushl $221
c0103262:	68 dd 00 00 00       	push   $0xdd
  jmp __alltraps
c0103267:	e9 98 01 00 00       	jmp    c0103404 <__alltraps>

c010326c <vector222>:
.globl vector222
vector222:
  pushl $0
c010326c:	6a 00                	push   $0x0
  pushl $222
c010326e:	68 de 00 00 00       	push   $0xde
  jmp __alltraps
c0103273:	e9 8c 01 00 00       	jmp    c0103404 <__alltraps>

c0103278 <vector223>:
.globl vector223
vector223:
  pushl $0
c0103278:	6a 00                	push   $0x0
  pushl $223
c010327a:	68 df 00 00 00       	push   $0xdf
  jmp __alltraps
c010327f:	e9 80 01 00 00       	jmp    c0103404 <__alltraps>

c0103284 <vector224>:
.globl vector224
vector224:
  pushl $0
c0103284:	6a 00                	push   $0x0
  pushl $224
c0103286:	68 e0 00 00 00       	push   $0xe0
  jmp __alltraps
c010328b:	e9 74 01 00 00       	jmp    c0103404 <__alltraps>

c0103290 <vector225>:
.globl vector225
vector225:
  pushl $0
c0103290:	6a 00                	push   $0x0
  pushl $225
c0103292:	68 e1 00 00 00       	push   $0xe1
  jmp __alltraps
c0103297:	e9 68 01 00 00       	jmp    c0103404 <__alltraps>

c010329c <vector226>:
.globl vector226
vector226:
  pushl $0
c010329c:	6a 00                	push   $0x0
  pushl $226
c010329e:	68 e2 00 00 00       	push   $0xe2
  jmp __alltraps
c01032a3:	e9 5c 01 00 00       	jmp    c0103404 <__alltraps>

c01032a8 <vector227>:
.globl vector227
vector227:
  pushl $0
c01032a8:	6a 00                	push   $0x0
  pushl $227
c01032aa:	68 e3 00 00 00       	push   $0xe3
  jmp __alltraps
c01032af:	e9 50 01 00 00       	jmp    c0103404 <__alltraps>

c01032b4 <vector228>:
.globl vector228
vector228:
  pushl $0
c01032b4:	6a 00                	push   $0x0
  pushl $228
c01032b6:	68 e4 00 00 00       	push   $0xe4
  jmp __alltraps
c01032bb:	e9 44 01 00 00       	jmp    c0103404 <__alltraps>

c01032c0 <vector229>:
.globl vector229
vector229:
  pushl $0
c01032c0:	6a 00                	push   $0x0
  pushl $229
c01032c2:	68 e5 00 00 00       	push   $0xe5
  jmp __alltraps
c01032c7:	e9 38 01 00 00       	jmp    c0103404 <__alltraps>

c01032cc <vector230>:
.globl vector230
vector230:
  pushl $0
c01032cc:	6a 00                	push   $0x0
  pushl $230
c01032ce:	68 e6 00 00 00       	push   $0xe6
  jmp __alltraps
c01032d3:	e9 2c 01 00 00       	jmp    c0103404 <__alltraps>

c01032d8 <vector231>:
.globl vector231
vector231:
  pushl $0
c01032d8:	6a 00                	push   $0x0
  pushl $231
c01032da:	68 e7 00 00 00       	push   $0xe7
  jmp __alltraps
c01032df:	e9 20 01 00 00       	jmp    c0103404 <__alltraps>

c01032e4 <vector232>:
.globl vector232
vector232:
  pushl $0
c01032e4:	6a 00                	push   $0x0
  pushl $232
c01032e6:	68 e8 00 00 00       	push   $0xe8
  jmp __alltraps
c01032eb:	e9 14 01 00 00       	jmp    c0103404 <__alltraps>

c01032f0 <vector233>:
.globl vector233
vector233:
  pushl $0
c01032f0:	6a 00                	push   $0x0
  pushl $233
c01032f2:	68 e9 00 00 00       	push   $0xe9
  jmp __alltraps
c01032f7:	e9 08 01 00 00       	jmp    c0103404 <__alltraps>

c01032fc <vector234>:
.globl vector234
vector234:
  pushl $0
c01032fc:	6a 00                	push   $0x0
  pushl $234
c01032fe:	68 ea 00 00 00       	push   $0xea
  jmp __alltraps
c0103303:	e9 fc 00 00 00       	jmp    c0103404 <__alltraps>

c0103308 <vector235>:
.globl vector235
vector235:
  pushl $0
c0103308:	6a 00                	push   $0x0
  pushl $235
c010330a:	68 eb 00 00 00       	push   $0xeb
  jmp __alltraps
c010330f:	e9 f0 00 00 00       	jmp    c0103404 <__alltraps>

c0103314 <vector236>:
.globl vector236
vector236:
  pushl $0
c0103314:	6a 00                	push   $0x0
  pushl $236
c0103316:	68 ec 00 00 00       	push   $0xec
  jmp __alltraps
c010331b:	e9 e4 00 00 00       	jmp    c0103404 <__alltraps>

c0103320 <vector237>:
.globl vector237
vector237:
  pushl $0
c0103320:	6a 00                	push   $0x0
  pushl $237
c0103322:	68 ed 00 00 00       	push   $0xed
  jmp __alltraps
c0103327:	e9 d8 00 00 00       	jmp    c0103404 <__alltraps>

c010332c <vector238>:
.globl vector238
vector238:
  pushl $0
c010332c:	6a 00                	push   $0x0
  pushl $238
c010332e:	68 ee 00 00 00       	push   $0xee
  jmp __alltraps
c0103333:	e9 cc 00 00 00       	jmp    c0103404 <__alltraps>

c0103338 <vector239>:
.globl vector239
vector239:
  pushl $0
c0103338:	6a 00                	push   $0x0
  pushl $239
c010333a:	68 ef 00 00 00       	push   $0xef
  jmp __alltraps
c010333f:	e9 c0 00 00 00       	jmp    c0103404 <__alltraps>

c0103344 <vector240>:
.globl vector240
vector240:
  pushl $0
c0103344:	6a 00                	push   $0x0
  pushl $240
c0103346:	68 f0 00 00 00       	push   $0xf0
  jmp __alltraps
c010334b:	e9 b4 00 00 00       	jmp    c0103404 <__alltraps>

c0103350 <vector241>:
.globl vector241
vector241:
  pushl $0
c0103350:	6a 00                	push   $0x0
  pushl $241
c0103352:	68 f1 00 00 00       	push   $0xf1
  jmp __alltraps
c0103357:	e9 a8 00 00 00       	jmp    c0103404 <__alltraps>

c010335c <vector242>:
.globl vector242
vector242:
  pushl $0
c010335c:	6a 00                	push   $0x0
  pushl $242
c010335e:	68 f2 00 00 00       	push   $0xf2
  jmp __alltraps
c0103363:	e9 9c 00 00 00       	jmp    c0103404 <__alltraps>

c0103368 <vector243>:
.globl vector243
vector243:
  pushl $0
c0103368:	6a 00                	push   $0x0
  pushl $243
c010336a:	68 f3 00 00 00       	push   $0xf3
  jmp __alltraps
c010336f:	e9 90 00 00 00       	jmp    c0103404 <__alltraps>

c0103374 <vector244>:
.globl vector244
vector244:
  pushl $0
c0103374:	6a 00                	push   $0x0
  pushl $244
c0103376:	68 f4 00 00 00       	push   $0xf4
  jmp __alltraps
c010337b:	e9 84 00 00 00       	jmp    c0103404 <__alltraps>

c0103380 <vector245>:
.globl vector245
vector245:
  pushl $0
c0103380:	6a 00                	push   $0x0
  pushl $245
c0103382:	68 f5 00 00 00       	push   $0xf5
  jmp __alltraps
c0103387:	e9 78 00 00 00       	jmp    c0103404 <__alltraps>

c010338c <vector246>:
.globl vector246
vector246:
  pushl $0
c010338c:	6a 00                	push   $0x0
  pushl $246
c010338e:	68 f6 00 00 00       	push   $0xf6
  jmp __alltraps
c0103393:	e9 6c 00 00 00       	jmp    c0103404 <__alltraps>

c0103398 <vector247>:
.globl vector247
vector247:
  pushl $0
c0103398:	6a 00                	push   $0x0
  pushl $247
c010339a:	68 f7 00 00 00       	push   $0xf7
  jmp __alltraps
c010339f:	e9 60 00 00 00       	jmp    c0103404 <__alltraps>

c01033a4 <vector248>:
.globl vector248
vector248:
  pushl $0
c01033a4:	6a 00                	push   $0x0
  pushl $248
c01033a6:	68 f8 00 00 00       	push   $0xf8
  jmp __alltraps
c01033ab:	e9 54 00 00 00       	jmp    c0103404 <__alltraps>

c01033b0 <vector249>:
.globl vector249
vector249:
  pushl $0
c01033b0:	6a 00                	push   $0x0
  pushl $249
c01033b2:	68 f9 00 00 00       	push   $0xf9
  jmp __alltraps
c01033b7:	e9 48 00 00 00       	jmp    c0103404 <__alltraps>

c01033bc <vector250>:
.globl vector250
vector250:
  pushl $0
c01033bc:	6a 00                	push   $0x0
  pushl $250
c01033be:	68 fa 00 00 00       	push   $0xfa
  jmp __alltraps
c01033c3:	e9 3c 00 00 00       	jmp    c0103404 <__alltraps>

c01033c8 <vector251>:
.globl vector251
vector251:
  pushl $0
c01033c8:	6a 00                	push   $0x0
  pushl $251
c01033ca:	68 fb 00 00 00       	push   $0xfb
  jmp __alltraps
c01033cf:	e9 30 00 00 00       	jmp    c0103404 <__alltraps>

c01033d4 <vector252>:
.globl vector252
vector252:
  pushl $0
c01033d4:	6a 00                	push   $0x0
  pushl $252
c01033d6:	68 fc 00 00 00       	push   $0xfc
  jmp __alltraps
c01033db:	e9 24 00 00 00       	jmp    c0103404 <__alltraps>

c01033e0 <vector253>:
.globl vector253
vector253:
  pushl $0
c01033e0:	6a 00                	push   $0x0
  pushl $253
c01033e2:	68 fd 00 00 00       	push   $0xfd
  jmp __alltraps
c01033e7:	e9 18 00 00 00       	jmp    c0103404 <__alltraps>

c01033ec <vector254>:
.globl vector254
vector254:
  pushl $0
c01033ec:	6a 00                	push   $0x0
  pushl $254
c01033ee:	68 fe 00 00 00       	push   $0xfe
  jmp __alltraps
c01033f3:	e9 0c 00 00 00       	jmp    c0103404 <__alltraps>

c01033f8 <vector255>:
.globl vector255
vector255:
  pushl $0
c01033f8:	6a 00                	push   $0x0
  pushl $255
c01033fa:	68 ff 00 00 00       	push   $0xff
  jmp __alltraps
c01033ff:	e9 00 00 00 00       	jmp    c0103404 <__alltraps>

c0103404 <__alltraps>:
.globl __alltraps
__alltraps:
    # push registers to build a trap frame
    # therefore make the stack look like a struct trapframe
    # 通过 push 指令，将数据段寄存器和所有通用寄存器（使用 pushal）的值压入栈中，以保存当前状态。
    pushl %ds
c0103404:	1e                   	push   %ds
    pushl %es
c0103405:	06                   	push   %es
    pushl %fs
c0103406:	0f a0                	push   %fs
    pushl %gs
c0103408:	0f a8                	push   %gs
    pushal
c010340a:	60                   	pusha  

    # load GD_KDATA into %ds and %es to set up data segments for kernel
    # 将常量 GD_KDATA 加载到 %eax 中，然后将其值复制到 %ds 和 %es 中，设置内核的数据段。
    movl $GD_KDATA, %eax
c010340b:	b8 10 00 00 00       	mov    $0x10,%eax
    movw %ax, %ds
c0103410:	8e d8                	mov    %eax,%ds
    movw %ax, %es
c0103412:	8e c0                	mov    %eax,%es

    # push %esp to pass a pointer to the trapframe as an argument to trap()
    # 将 %esp 压栈，以将指向 trapframe 的指针作为参数传递给 trap()
    pushl %esp
c0103414:	54                   	push   %esp

    # call trap(tf), where tf=%esp
    # 调用 trap(tf)，其中 tf=%esp
    call trap
c0103415:	e8 60 f5 ff ff       	call   c010297a <trap>

    # pop the pushed stack pointer弹出之前压入的栈指针
    popl %esp
c010341a:	5c                   	pop    %esp

c010341b <__trapret>:
    # 返回后继续执行到 trapret...
.globl __trapret
__trapret:
    # restore registers from stack
    # 定义了返回的入口点 __trapret。
    popal
c010341b:	61                   	popa   

    # restore %ds, %es, %fs and %gs
    # 这里会恢复之前保存的寄存器
    popl %gs
c010341c:	0f a9                	pop    %gs
    popl %fs
c010341e:	0f a1                	pop    %fs
    popl %es
c0103420:	07                   	pop    %es
    popl %ds
c0103421:	1f                   	pop    %ds

    # get rid of the trap number and error code
    # 通过 iret 指令返回中断处理
    addl $0x8, %esp
c0103422:	83 c4 08             	add    $0x8,%esp
    iret
c0103425:	cf                   	iret   

c0103426 <page2ppn>:

extern struct Page *pages;
extern size_t npage;

static inline ppn_t
page2ppn(struct Page *page) {
c0103426:	55                   	push   %ebp
c0103427:	89 e5                	mov    %esp,%ebp
    return page - pages;
c0103429:	a1 78 70 12 c0       	mov    0xc0127078,%eax
c010342e:	8b 55 08             	mov    0x8(%ebp),%edx
c0103431:	29 c2                	sub    %eax,%edx
c0103433:	89 d0                	mov    %edx,%eax
c0103435:	c1 f8 05             	sar    $0x5,%eax
}
c0103438:	5d                   	pop    %ebp
c0103439:	c3                   	ret    

c010343a <page2pa>:

static inline uintptr_t
page2pa(struct Page *page) {
c010343a:	55                   	push   %ebp
c010343b:	89 e5                	mov    %esp,%ebp
c010343d:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0103440:	8b 45 08             	mov    0x8(%ebp),%eax
c0103443:	89 04 24             	mov    %eax,(%esp)
c0103446:	e8 db ff ff ff       	call   c0103426 <page2ppn>
c010344b:	c1 e0 0c             	shl    $0xc,%eax
}
c010344e:	c9                   	leave  
c010344f:	c3                   	ret    

c0103450 <pa2page>:

static inline struct Page *
pa2page(uintptr_t pa) {
c0103450:	55                   	push   %ebp
c0103451:	89 e5                	mov    %esp,%ebp
c0103453:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c0103456:	8b 45 08             	mov    0x8(%ebp),%eax
c0103459:	c1 e8 0c             	shr    $0xc,%eax
c010345c:	89 c2                	mov    %eax,%edx
c010345e:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c0103463:	39 c2                	cmp    %eax,%edx
c0103465:	72 1c                	jb     c0103483 <pa2page+0x33>
        panic("pa2page called with invalid pa");
c0103467:	c7 44 24 08 f0 98 10 	movl   $0xc01098f0,0x8(%esp)
c010346e:	c0 
c010346f:	c7 44 24 04 5b 00 00 	movl   $0x5b,0x4(%esp)
c0103476:	00 
c0103477:	c7 04 24 0f 99 10 c0 	movl   $0xc010990f,(%esp)
c010347e:	e8 c2 cf ff ff       	call   c0100445 <__panic>
    }
    return &pages[PPN(pa)];
c0103483:	a1 78 70 12 c0       	mov    0xc0127078,%eax
c0103488:	8b 55 08             	mov    0x8(%ebp),%edx
c010348b:	c1 ea 0c             	shr    $0xc,%edx
c010348e:	c1 e2 05             	shl    $0x5,%edx
c0103491:	01 d0                	add    %edx,%eax
}
c0103493:	c9                   	leave  
c0103494:	c3                   	ret    

c0103495 <page2kva>:

static inline void *
page2kva(struct Page *page) {
c0103495:	55                   	push   %ebp
c0103496:	89 e5                	mov    %esp,%ebp
c0103498:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c010349b:	8b 45 08             	mov    0x8(%ebp),%eax
c010349e:	89 04 24             	mov    %eax,(%esp)
c01034a1:	e8 94 ff ff ff       	call   c010343a <page2pa>
c01034a6:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01034a9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01034ac:	c1 e8 0c             	shr    $0xc,%eax
c01034af:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01034b2:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c01034b7:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01034ba:	72 23                	jb     c01034df <page2kva+0x4a>
c01034bc:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01034bf:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01034c3:	c7 44 24 08 20 99 10 	movl   $0xc0109920,0x8(%esp)
c01034ca:	c0 
c01034cb:	c7 44 24 04 62 00 00 	movl   $0x62,0x4(%esp)
c01034d2:	00 
c01034d3:	c7 04 24 0f 99 10 c0 	movl   $0xc010990f,(%esp)
c01034da:	e8 66 cf ff ff       	call   c0100445 <__panic>
c01034df:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01034e2:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c01034e7:	c9                   	leave  
c01034e8:	c3                   	ret    

c01034e9 <kva2page>:

static inline struct Page *
kva2page(void *kva) {
c01034e9:	55                   	push   %ebp
c01034ea:	89 e5                	mov    %esp,%ebp
c01034ec:	83 ec 28             	sub    $0x28,%esp
    return pa2page(PADDR(kva));
c01034ef:	8b 45 08             	mov    0x8(%ebp),%eax
c01034f2:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01034f5:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c01034fc:	77 23                	ja     c0103521 <kva2page+0x38>
c01034fe:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103501:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0103505:	c7 44 24 08 44 99 10 	movl   $0xc0109944,0x8(%esp)
c010350c:	c0 
c010350d:	c7 44 24 04 67 00 00 	movl   $0x67,0x4(%esp)
c0103514:	00 
c0103515:	c7 04 24 0f 99 10 c0 	movl   $0xc010990f,(%esp)
c010351c:	e8 24 cf ff ff       	call   c0100445 <__panic>
c0103521:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103524:	05 00 00 00 40       	add    $0x40000000,%eax
c0103529:	89 04 24             	mov    %eax,(%esp)
c010352c:	e8 1f ff ff ff       	call   c0103450 <pa2page>
}
c0103531:	c9                   	leave  
c0103532:	c3                   	ret    

c0103533 <pte2page>:

static inline struct Page *
pte2page(pte_t pte) {
c0103533:	55                   	push   %ebp
c0103534:	89 e5                	mov    %esp,%ebp
c0103536:	83 ec 18             	sub    $0x18,%esp
    if (!(pte & PTE_P)) {
c0103539:	8b 45 08             	mov    0x8(%ebp),%eax
c010353c:	83 e0 01             	and    $0x1,%eax
c010353f:	85 c0                	test   %eax,%eax
c0103541:	75 1c                	jne    c010355f <pte2page+0x2c>
        panic("pte2page called with invalid pte");
c0103543:	c7 44 24 08 68 99 10 	movl   $0xc0109968,0x8(%esp)
c010354a:	c0 
c010354b:	c7 44 24 04 6d 00 00 	movl   $0x6d,0x4(%esp)
c0103552:	00 
c0103553:	c7 04 24 0f 99 10 c0 	movl   $0xc010990f,(%esp)
c010355a:	e8 e6 ce ff ff       	call   c0100445 <__panic>
    }
    return pa2page(PTE_ADDR(pte));
c010355f:	8b 45 08             	mov    0x8(%ebp),%eax
c0103562:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0103567:	89 04 24             	mov    %eax,(%esp)
c010356a:	e8 e1 fe ff ff       	call   c0103450 <pa2page>
}
c010356f:	c9                   	leave  
c0103570:	c3                   	ret    

c0103571 <pde2page>:

static inline struct Page *
pde2page(pde_t pde) {
c0103571:	55                   	push   %ebp
c0103572:	89 e5                	mov    %esp,%ebp
c0103574:	83 ec 18             	sub    $0x18,%esp
    return pa2page(PDE_ADDR(pde));
c0103577:	8b 45 08             	mov    0x8(%ebp),%eax
c010357a:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010357f:	89 04 24             	mov    %eax,(%esp)
c0103582:	e8 c9 fe ff ff       	call   c0103450 <pa2page>
}
c0103587:	c9                   	leave  
c0103588:	c3                   	ret    

c0103589 <page_ref>:

static inline int
page_ref(struct Page *page) {
c0103589:	55                   	push   %ebp
c010358a:	89 e5                	mov    %esp,%ebp
    return page->ref;
c010358c:	8b 45 08             	mov    0x8(%ebp),%eax
c010358f:	8b 00                	mov    (%eax),%eax
}
c0103591:	5d                   	pop    %ebp
c0103592:	c3                   	ret    

c0103593 <set_page_ref>:

static inline void
set_page_ref(struct Page *page, int val) {
c0103593:	55                   	push   %ebp
c0103594:	89 e5                	mov    %esp,%ebp
    page->ref = val;
c0103596:	8b 45 08             	mov    0x8(%ebp),%eax
c0103599:	8b 55 0c             	mov    0xc(%ebp),%edx
c010359c:	89 10                	mov    %edx,(%eax)
}
c010359e:	90                   	nop
c010359f:	5d                   	pop    %ebp
c01035a0:	c3                   	ret    

c01035a1 <page_ref_inc>:

static inline int
page_ref_inc(struct Page *page) {
c01035a1:	55                   	push   %ebp
c01035a2:	89 e5                	mov    %esp,%ebp
    page->ref += 1;
c01035a4:	8b 45 08             	mov    0x8(%ebp),%eax
c01035a7:	8b 00                	mov    (%eax),%eax
c01035a9:	8d 50 01             	lea    0x1(%eax),%edx
c01035ac:	8b 45 08             	mov    0x8(%ebp),%eax
c01035af:	89 10                	mov    %edx,(%eax)
    return page->ref;
c01035b1:	8b 45 08             	mov    0x8(%ebp),%eax
c01035b4:	8b 00                	mov    (%eax),%eax
}
c01035b6:	5d                   	pop    %ebp
c01035b7:	c3                   	ret    

c01035b8 <page_ref_dec>:

static inline int
page_ref_dec(struct Page *page) {
c01035b8:	55                   	push   %ebp
c01035b9:	89 e5                	mov    %esp,%ebp
    page->ref -= 1;
c01035bb:	8b 45 08             	mov    0x8(%ebp),%eax
c01035be:	8b 00                	mov    (%eax),%eax
c01035c0:	8d 50 ff             	lea    -0x1(%eax),%edx
c01035c3:	8b 45 08             	mov    0x8(%ebp),%eax
c01035c6:	89 10                	mov    %edx,(%eax)
    return page->ref;
c01035c8:	8b 45 08             	mov    0x8(%ebp),%eax
c01035cb:	8b 00                	mov    (%eax),%eax
}
c01035cd:	5d                   	pop    %ebp
c01035ce:	c3                   	ret    

c01035cf <__intr_save>:
__intr_save(void) {
c01035cf:	55                   	push   %ebp
c01035d0:	89 e5                	mov    %esp,%ebp
c01035d2:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c01035d5:	9c                   	pushf  
c01035d6:	58                   	pop    %eax
c01035d7:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c01035da:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c01035dd:	25 00 02 00 00       	and    $0x200,%eax
c01035e2:	85 c0                	test   %eax,%eax
c01035e4:	74 0c                	je     c01035f2 <__intr_save+0x23>
        intr_disable();
c01035e6:	e8 6b eb ff ff       	call   c0102156 <intr_disable>
        return 1;
c01035eb:	b8 01 00 00 00       	mov    $0x1,%eax
c01035f0:	eb 05                	jmp    c01035f7 <__intr_save+0x28>
    return 0;
c01035f2:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01035f7:	c9                   	leave  
c01035f8:	c3                   	ret    

c01035f9 <__intr_restore>:
__intr_restore(bool flag) {
c01035f9:	55                   	push   %ebp
c01035fa:	89 e5                	mov    %esp,%ebp
c01035fc:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c01035ff:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0103603:	74 05                	je     c010360a <__intr_restore+0x11>
        intr_enable();
c0103605:	e8 40 eb ff ff       	call   c010214a <intr_enable>
}
c010360a:	90                   	nop
c010360b:	c9                   	leave  
c010360c:	c3                   	ret    

c010360d <lgdt>:
 * data/code segement registers for kernel.
 * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。
 * */
//定义了一个静态内联函数 lgdt，接收一个指向伪描述符（struct pseudodesc）的指针 pd
static inline void
lgdt(struct pseudodesc *pd) {
c010360d:	55                   	push   %ebp
c010360e:	89 e5                	mov    %esp,%ebp
    //这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针，告诉处理器 GDT 的地址。
    asm volatile ("lgdt (%0)" :: "r" (pd));
c0103610:	8b 45 08             	mov    0x8(%ebp),%eax
c0103613:	0f 01 10             	lgdtl  (%eax)
    asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS（用户数据段）的值移动到 gs 段寄存器。
c0103616:	b8 23 00 00 00       	mov    $0x23,%eax
c010361b:	8e e8                	mov    %eax,%gs
    asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。
c010361d:	b8 23 00 00 00       	mov    $0x23,%eax
c0103622:	8e e0                	mov    %eax,%fs
    asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS（内核数据段）的值移动到 es 段寄存器。
c0103624:	b8 10 00 00 00       	mov    $0x10,%eax
c0103629:	8e c0                	mov    %eax,%es
    asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器
c010362b:	b8 10 00 00 00       	mov    $0x10,%eax
c0103630:	8e d8                	mov    %eax,%ds
    asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器
c0103632:	b8 10 00 00 00       	mov    $0x10,%eax
c0103637:	8e d0                	mov    %eax,%ss
    // reload cs
    //通过 ljmp 指令重新加载代码段寄存器 cs，并跳转到标签 1。
    asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS));
c0103639:	ea 40 36 10 c0 08 00 	ljmp   $0x8,$0xc0103640
}
c0103640:	90                   	nop
c0103641:	5d                   	pop    %ebp
c0103642:	c3                   	ret    

c0103643 <load_esp0>:
 * load_esp0 - 修改默认任务状态段中的 ESP0，以便在从用户态陷入内核态时能够使用不同的内核栈。
 * */
//uintptr_t esp0：这是新的堆栈指针，通常指向内核栈的顶部。
//修改当前任务状态段（TSS）中的 ESP0 值。ESP0 是在从用户态切换到内核态时，CPU 使用的内核栈指针。
void
load_esp0(uintptr_t esp0) {
c0103643:	f3 0f 1e fb          	endbr32 
c0103647:	55                   	push   %ebp
c0103648:	89 e5                	mov    %esp,%ebp
    ts.ts_esp0 = esp0;
c010364a:	8b 45 08             	mov    0x8(%ebp),%eax
c010364d:	a3 a4 6f 12 c0       	mov    %eax,0xc0126fa4
}
c0103652:	90                   	nop
c0103653:	5d                   	pop    %ebp
c0103654:	c3                   	ret    

c0103655 <gdt_init>:

/* gdt_init - initialize the default GDT and TSS */
/* gdt_init - 初始化默认的 GDT 和 TSS */
static void
gdt_init(void) {
c0103655:	f3 0f 1e fb          	endbr32 
c0103659:	55                   	push   %ebp
c010365a:	89 e5                	mov    %esp,%ebp
c010365c:	83 ec 14             	sub    $0x14,%esp
    // 设置启动内核栈和默认的 SS0
    // set boot kernel stack and default SS0
    load_esp0((uintptr_t)bootstacktop);
c010365f:	b8 00 30 12 c0       	mov    $0xc0123000,%eax
c0103664:	89 04 24             	mov    %eax,(%esp)
c0103667:	e8 d7 ff ff ff       	call   c0103643 <load_esp0>
    ts.ts_ss0 = KERNEL_DS;
c010366c:	66 c7 05 a8 6f 12 c0 	movw   $0x10,0xc0126fa8
c0103673:	10 00 
    // 初始化 GDT 中的 TSS 字段
    // initialize the TSS filed of the gdt
    gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL);
c0103675:	66 c7 05 28 3a 12 c0 	movw   $0x68,0xc0123a28
c010367c:	68 00 
c010367e:	b8 a0 6f 12 c0       	mov    $0xc0126fa0,%eax
c0103683:	0f b7 c0             	movzwl %ax,%eax
c0103686:	66 a3 2a 3a 12 c0    	mov    %ax,0xc0123a2a
c010368c:	b8 a0 6f 12 c0       	mov    $0xc0126fa0,%eax
c0103691:	c1 e8 10             	shr    $0x10,%eax
c0103694:	a2 2c 3a 12 c0       	mov    %al,0xc0123a2c
c0103699:	0f b6 05 2d 3a 12 c0 	movzbl 0xc0123a2d,%eax
c01036a0:	24 f0                	and    $0xf0,%al
c01036a2:	0c 09                	or     $0x9,%al
c01036a4:	a2 2d 3a 12 c0       	mov    %al,0xc0123a2d
c01036a9:	0f b6 05 2d 3a 12 c0 	movzbl 0xc0123a2d,%eax
c01036b0:	24 ef                	and    $0xef,%al
c01036b2:	a2 2d 3a 12 c0       	mov    %al,0xc0123a2d
c01036b7:	0f b6 05 2d 3a 12 c0 	movzbl 0xc0123a2d,%eax
c01036be:	24 9f                	and    $0x9f,%al
c01036c0:	a2 2d 3a 12 c0       	mov    %al,0xc0123a2d
c01036c5:	0f b6 05 2d 3a 12 c0 	movzbl 0xc0123a2d,%eax
c01036cc:	0c 80                	or     $0x80,%al
c01036ce:	a2 2d 3a 12 c0       	mov    %al,0xc0123a2d
c01036d3:	0f b6 05 2e 3a 12 c0 	movzbl 0xc0123a2e,%eax
c01036da:	24 f0                	and    $0xf0,%al
c01036dc:	a2 2e 3a 12 c0       	mov    %al,0xc0123a2e
c01036e1:	0f b6 05 2e 3a 12 c0 	movzbl 0xc0123a2e,%eax
c01036e8:	24 ef                	and    $0xef,%al
c01036ea:	a2 2e 3a 12 c0       	mov    %al,0xc0123a2e
c01036ef:	0f b6 05 2e 3a 12 c0 	movzbl 0xc0123a2e,%eax
c01036f6:	24 df                	and    $0xdf,%al
c01036f8:	a2 2e 3a 12 c0       	mov    %al,0xc0123a2e
c01036fd:	0f b6 05 2e 3a 12 c0 	movzbl 0xc0123a2e,%eax
c0103704:	0c 40                	or     $0x40,%al
c0103706:	a2 2e 3a 12 c0       	mov    %al,0xc0123a2e
c010370b:	0f b6 05 2e 3a 12 c0 	movzbl 0xc0123a2e,%eax
c0103712:	24 7f                	and    $0x7f,%al
c0103714:	a2 2e 3a 12 c0       	mov    %al,0xc0123a2e
c0103719:	b8 a0 6f 12 c0       	mov    $0xc0126fa0,%eax
c010371e:	c1 e8 18             	shr    $0x18,%eax
c0103721:	a2 2f 3a 12 c0       	mov    %al,0xc0123a2f
    // 使用lgdt加载全局描述符表，更新所有段寄存器
    // reload all segment registers
    lgdt(&gdt_pd);
c0103726:	c7 04 24 30 3a 12 c0 	movl   $0xc0123a30,(%esp)
c010372d:	e8 db fe ff ff       	call   c010360d <lgdt>
c0103732:	66 c7 45 fe 28 00    	movw   $0x28,-0x2(%ebp)
    asm volatile ("ltr %0" :: "r" (sel) : "memory");
c0103738:	0f b7 45 fe          	movzwl -0x2(%ebp),%eax
c010373c:	0f 00 d8             	ltr    %ax
}
c010373f:	90                   	nop
    // 加载 TSS，使 CPU 在进行特权级切换时能够正确使用 TSS。
    // load the TSS
    ltr(GD_TSS);
}
c0103740:	90                   	nop
c0103741:	c9                   	leave  
c0103742:	c3                   	ret    

c0103743 <init_pmm_manager>:

//init_pmm_manager - initialize a pmm_manager instance
//初始化一个 pmm_manager 实例
static void
init_pmm_manager(void) {
c0103743:	f3 0f 1e fb          	endbr32 
c0103747:	55                   	push   %ebp
c0103748:	89 e5                	mov    %esp,%ebp
c010374a:	83 ec 18             	sub    $0x18,%esp
    //将 pmm_manager 指向默认的 PMM 管理器实例。
    pmm_manager = &default_pmm_manager;
c010374d:	c7 05 70 70 12 c0 cc 	movl   $0xc010adcc,0xc0127070
c0103754:	ad 10 c0 
     //使用 cprintf 打印当前内存管理器的名称。
    cprintf("memory management: %s\n", pmm_manager->name);
c0103757:	a1 70 70 12 c0       	mov    0xc0127070,%eax
c010375c:	8b 00                	mov    (%eax),%eax
c010375e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0103762:	c7 04 24 94 99 10 c0 	movl   $0xc0109994,(%esp)
c0103769:	e8 6b cb ff ff       	call   c01002d9 <cprintf>
    //调用 PMM 管理器的初始化函数，以设置和准备内存管理的相关数据结构。
    pmm_manager->init();
c010376e:	a1 70 70 12 c0       	mov    0xc0127070,%eax
c0103773:	8b 40 04             	mov    0x4(%eax),%eax
c0103776:	ff d0                	call   *%eax
}
c0103778:	90                   	nop
c0103779:	c9                   	leave  
c010377a:	c3                   	ret    

c010377b <init_memmap>:

//init_memmap - call pmm->init_memmap to build Page struct for free memory 
// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构
//struct Page *base：指向内存页的基础地址。 size_t n：要初始化的页数。 
static void
init_memmap(struct Page *base, size_t n) {
c010377b:	f3 0f 1e fb          	endbr32 
c010377f:	55                   	push   %ebp
c0103780:	89 e5                	mov    %esp,%ebp
c0103782:	83 ec 18             	sub    $0x18,%esp
    pmm_manager->init_memmap(base, n);
c0103785:	a1 70 70 12 c0       	mov    0xc0127070,%eax
c010378a:	8b 40 08             	mov    0x8(%eax),%eax
c010378d:	8b 55 0c             	mov    0xc(%ebp),%edx
c0103790:	89 54 24 04          	mov    %edx,0x4(%esp)
c0103794:	8b 55 08             	mov    0x8(%ebp),%edx
c0103797:	89 14 24             	mov    %edx,(%esp)
c010379a:	ff d0                	call   *%eax
}
c010379c:	90                   	nop
c010379d:	c9                   	leave  
c010379e:	c3                   	ret    

c010379f <alloc_pages>:

//alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory 
// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存
struct Page *
alloc_pages(size_t n) {
c010379f:	f3 0f 1e fb          	endbr32 
c01037a3:	55                   	push   %ebp
c01037a4:	89 e5                	mov    %esp,%ebp
c01037a6:	83 ec 28             	sub    $0x28,%esp
    struct Page *page=NULL;
c01037a9:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    bool intr_flag;
    //使用 local_intr_save 保存当前的中断状态，以避免在分配内存时发生中断。    
    while (1)
    {
         local_intr_save(intr_flag);
c01037b0:	e8 1a fe ff ff       	call   c01035cf <__intr_save>
c01037b5:	89 45 f0             	mov    %eax,-0x10(%ebp)
         {
              page = pmm_manager->alloc_pages(n);//尝试分配 n 个页面。
c01037b8:	a1 70 70 12 c0       	mov    0xc0127070,%eax
c01037bd:	8b 40 0c             	mov    0xc(%eax),%eax
c01037c0:	8b 55 08             	mov    0x8(%ebp),%edx
c01037c3:	89 14 24             	mov    %edx,(%esp)
c01037c6:	ff d0                	call   *%eax
c01037c8:	89 45 f4             	mov    %eax,-0xc(%ebp)
         }
         local_intr_restore(intr_flag);
c01037cb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01037ce:	89 04 24             	mov    %eax,(%esp)
c01037d1:	e8 23 fe ff ff       	call   c01035f9 <__intr_restore>

         if (page != NULL || n > 1 || swap_init_ok == 0) break;
c01037d6:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01037da:	75 2d                	jne    c0103809 <alloc_pages+0x6a>
c01037dc:	83 7d 08 01          	cmpl   $0x1,0x8(%ebp)
c01037e0:	77 27                	ja     c0103809 <alloc_pages+0x6a>
c01037e2:	a1 10 70 12 c0       	mov    0xc0127010,%eax
c01037e7:	85 c0                	test   %eax,%eax
c01037e9:	74 1e                	je     c0103809 <alloc_pages+0x6a>
         
         extern struct mm_struct *check_mm_struct;
         //cprintf("page %x, call swap_out in alloc_pages %d\n",page, n);
         swap_out(check_mm_struct, n, 0);
c01037eb:	8b 55 08             	mov    0x8(%ebp),%edx
c01037ee:	a1 84 70 12 c0       	mov    0xc0127084,%eax
c01037f3:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01037fa:	00 
c01037fb:	89 54 24 04          	mov    %edx,0x4(%esp)
c01037ff:	89 04 24             	mov    %eax,(%esp)
c0103802:	e8 64 2d 00 00       	call   c010656b <swap_out>
    {
c0103807:	eb a7                	jmp    c01037b0 <alloc_pages+0x11>
    }
    //cprintf("n %d,get page %x, No %d in alloc_pages\n",n,page,(page-pages));
    return page;
c0103809:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010380c:	c9                   	leave  
c010380d:	c3                   	ret    

c010380e <free_pages>:

//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory 
// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存
//struct Page *base：指向要释放的内存页的基础地址。size_t n：要释放的页数。
void
free_pages(struct Page *base, size_t n) {
c010380e:	f3 0f 1e fb          	endbr32 
c0103812:	55                   	push   %ebp
c0103813:	89 e5                	mov    %esp,%ebp
c0103815:	83 ec 28             	sub    $0x28,%esp
    bool intr_flag;
    //使用 local_intr_save 保存当前的中断状态，以避免在释放内存时发生中断。
    local_intr_save(intr_flag);
c0103818:	e8 b2 fd ff ff       	call   c01035cf <__intr_save>
c010381d:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        //调用物理内存管理器的 free_pages 函数释放 n 页的内存。
        pmm_manager->free_pages(base, n);
c0103820:	a1 70 70 12 c0       	mov    0xc0127070,%eax
c0103825:	8b 40 10             	mov    0x10(%eax),%eax
c0103828:	8b 55 0c             	mov    0xc(%ebp),%edx
c010382b:	89 54 24 04          	mov    %edx,0x4(%esp)
c010382f:	8b 55 08             	mov    0x8(%ebp),%edx
c0103832:	89 14 24             	mov    %edx,(%esp)
c0103835:	ff d0                	call   *%eax
    }
    local_intr_restore(intr_flag);
c0103837:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010383a:	89 04 24             	mov    %eax,(%esp)
c010383d:	e8 b7 fd ff ff       	call   c01035f9 <__intr_restore>
}
c0103842:	90                   	nop
c0103843:	c9                   	leave  
c0103844:	c3                   	ret    

c0103845 <nr_free_pages>:

//nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) 
//of current free memory
// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE)
size_t
nr_free_pages(void) {
c0103845:	f3 0f 1e fb          	endbr32 
c0103849:	55                   	push   %ebp
c010384a:	89 e5                	mov    %esp,%ebp
c010384c:	83 ec 28             	sub    $0x28,%esp
    size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小
    bool intr_flag;// 定义变量 intr_flag 用于保存中断状态
    local_intr_save(intr_flag);// 保存当前中断状态，并禁用中断
c010384f:	e8 7b fd ff ff       	call   c01035cf <__intr_save>
c0103854:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数
c0103857:	a1 70 70 12 c0       	mov    0xc0127070,%eax
c010385c:	8b 40 14             	mov    0x14(%eax),%eax
c010385f:	ff d0                	call   *%eax
c0103861:	89 45 f0             	mov    %eax,-0x10(%ebp)
    }
    local_intr_restore(intr_flag);// 恢复之前保存的中断状态
c0103864:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103867:	89 04 24             	mov    %eax,(%esp)
c010386a:	e8 8a fd ff ff       	call   c01035f9 <__intr_restore>
    return ret;// 返回空闲内存的大小
c010386f:	8b 45 f0             	mov    -0x10(%ebp),%eax
}
c0103872:	c9                   	leave  
c0103873:	c3                   	ret    

c0103874 <page_init>:

/* pmm_init - initialize the physical memory management */
/* pmm_init - 初始化物理内存管理 */
static void
page_init(void) {
c0103874:	f3 0f 1e fb          	endbr32 
c0103878:	55                   	push   %ebp
c0103879:	89 e5                	mov    %esp,%ebp
c010387b:	57                   	push   %edi
c010387c:	56                   	push   %esi
c010387d:	53                   	push   %ebx
c010387e:	81 ec 9c 00 00 00    	sub    $0x9c,%esp
    // 获取物理内存映射信息，存于特定地址
    struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE);
c0103884:	c7 45 c4 00 80 00 c0 	movl   $0xc0008000,-0x3c(%ebp)
    uint64_t maxpa = 0;// 初始化最大物理地址为0
c010388b:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
c0103892:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
    
    cprintf("e820map:\n");// 打印“e820map”标题
c0103899:	c7 04 24 ab 99 10 c0 	movl   $0xc01099ab,(%esp)
c01038a0:	e8 34 ca ff ff       	call   c01002d9 <cprintf>
    int i;
    for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组
c01038a5:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c01038ac:	e9 1a 01 00 00       	jmp    c01039cb <page_init+0x157>
        uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址
c01038b1:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01038b4:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01038b7:	89 d0                	mov    %edx,%eax
c01038b9:	c1 e0 02             	shl    $0x2,%eax
c01038bc:	01 d0                	add    %edx,%eax
c01038be:	c1 e0 02             	shl    $0x2,%eax
c01038c1:	01 c8                	add    %ecx,%eax
c01038c3:	8b 50 08             	mov    0x8(%eax),%edx
c01038c6:	8b 40 04             	mov    0x4(%eax),%eax
c01038c9:	89 45 a0             	mov    %eax,-0x60(%ebp)
c01038cc:	89 55 a4             	mov    %edx,-0x5c(%ebp)
c01038cf:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01038d2:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01038d5:	89 d0                	mov    %edx,%eax
c01038d7:	c1 e0 02             	shl    $0x2,%eax
c01038da:	01 d0                	add    %edx,%eax
c01038dc:	c1 e0 02             	shl    $0x2,%eax
c01038df:	01 c8                	add    %ecx,%eax
c01038e1:	8b 48 0c             	mov    0xc(%eax),%ecx
c01038e4:	8b 58 10             	mov    0x10(%eax),%ebx
c01038e7:	8b 45 a0             	mov    -0x60(%ebp),%eax
c01038ea:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c01038ed:	01 c8                	add    %ecx,%eax
c01038ef:	11 da                	adc    %ebx,%edx
c01038f1:	89 45 98             	mov    %eax,-0x68(%ebp)
c01038f4:	89 55 9c             	mov    %edx,-0x64(%ebp)
        cprintf("  memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息
c01038f7:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01038fa:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01038fd:	89 d0                	mov    %edx,%eax
c01038ff:	c1 e0 02             	shl    $0x2,%eax
c0103902:	01 d0                	add    %edx,%eax
c0103904:	c1 e0 02             	shl    $0x2,%eax
c0103907:	01 c8                	add    %ecx,%eax
c0103909:	83 c0 14             	add    $0x14,%eax
c010390c:	8b 00                	mov    (%eax),%eax
c010390e:	89 45 84             	mov    %eax,-0x7c(%ebp)
c0103911:	8b 45 98             	mov    -0x68(%ebp),%eax
c0103914:	8b 55 9c             	mov    -0x64(%ebp),%edx
c0103917:	83 c0 ff             	add    $0xffffffff,%eax
c010391a:	83 d2 ff             	adc    $0xffffffff,%edx
c010391d:	89 85 78 ff ff ff    	mov    %eax,-0x88(%ebp)
c0103923:	89 95 7c ff ff ff    	mov    %edx,-0x84(%ebp)
c0103929:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c010392c:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010392f:	89 d0                	mov    %edx,%eax
c0103931:	c1 e0 02             	shl    $0x2,%eax
c0103934:	01 d0                	add    %edx,%eax
c0103936:	c1 e0 02             	shl    $0x2,%eax
c0103939:	01 c8                	add    %ecx,%eax
c010393b:	8b 48 0c             	mov    0xc(%eax),%ecx
c010393e:	8b 58 10             	mov    0x10(%eax),%ebx
c0103941:	8b 55 84             	mov    -0x7c(%ebp),%edx
c0103944:	89 54 24 1c          	mov    %edx,0x1c(%esp)
c0103948:	8b 85 78 ff ff ff    	mov    -0x88(%ebp),%eax
c010394e:	8b 95 7c ff ff ff    	mov    -0x84(%ebp),%edx
c0103954:	89 44 24 14          	mov    %eax,0x14(%esp)
c0103958:	89 54 24 18          	mov    %edx,0x18(%esp)
c010395c:	8b 45 a0             	mov    -0x60(%ebp),%eax
c010395f:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c0103962:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0103966:	89 54 24 10          	mov    %edx,0x10(%esp)
c010396a:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c010396e:	89 5c 24 08          	mov    %ebx,0x8(%esp)
c0103972:	c7 04 24 b8 99 10 c0 	movl   $0xc01099b8,(%esp)
c0103979:	e8 5b c9 ff ff       	call   c01002d9 <cprintf>
                memmap->map[i].size, begin, end - 1, memmap->map[i].type);
        if (memmap->map[i].type == E820_ARM) {// 检查内存类型是否为可用内存
c010397e:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0103981:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103984:	89 d0                	mov    %edx,%eax
c0103986:	c1 e0 02             	shl    $0x2,%eax
c0103989:	01 d0                	add    %edx,%eax
c010398b:	c1 e0 02             	shl    $0x2,%eax
c010398e:	01 c8                	add    %ecx,%eax
c0103990:	83 c0 14             	add    $0x14,%eax
c0103993:	8b 00                	mov    (%eax),%eax
c0103995:	83 f8 01             	cmp    $0x1,%eax
c0103998:	75 2e                	jne    c01039c8 <page_init+0x154>
            if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内
c010399a:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010399d:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01039a0:	3b 45 98             	cmp    -0x68(%ebp),%eax
c01039a3:	89 d0                	mov    %edx,%eax
c01039a5:	1b 45 9c             	sbb    -0x64(%ebp),%eax
c01039a8:	73 1e                	jae    c01039c8 <page_init+0x154>
c01039aa:	ba ff ff ff 37       	mov    $0x37ffffff,%edx
c01039af:	b8 00 00 00 00       	mov    $0x0,%eax
c01039b4:	3b 55 a0             	cmp    -0x60(%ebp),%edx
c01039b7:	1b 45 a4             	sbb    -0x5c(%ebp),%eax
c01039ba:	72 0c                	jb     c01039c8 <page_init+0x154>
                maxpa = end;// 更新最大物理地址
c01039bc:	8b 45 98             	mov    -0x68(%ebp),%eax
c01039bf:	8b 55 9c             	mov    -0x64(%ebp),%edx
c01039c2:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01039c5:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组
c01039c8:	ff 45 dc             	incl   -0x24(%ebp)
c01039cb:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c01039ce:	8b 00                	mov    (%eax),%eax
c01039d0:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c01039d3:	0f 8c d8 fe ff ff    	jl     c01038b1 <page_init+0x3d>
            }
        }
    }
    if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限
c01039d9:	ba 00 00 00 38       	mov    $0x38000000,%edx
c01039de:	b8 00 00 00 00       	mov    $0x0,%eax
c01039e3:	3b 55 e0             	cmp    -0x20(%ebp),%edx
c01039e6:	1b 45 e4             	sbb    -0x1c(%ebp),%eax
c01039e9:	73 0e                	jae    c01039f9 <page_init+0x185>
        maxpa = KMEMSIZE;// 将其限制为内存上限
c01039eb:	c7 45 e0 00 00 00 38 	movl   $0x38000000,-0x20(%ebp)
c01039f2:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
    }

    extern char end[];// 引入全局变量 end，指向内存的结束位置

    npage = maxpa / PGSIZE;// 计算可用页数
c01039f9:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01039fc:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01039ff:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c0103a03:	c1 ea 0c             	shr    $0xc,%edx
c0103a06:	a3 80 6f 12 c0       	mov    %eax,0xc0126f80
    pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界，指向页结构数组的开头
c0103a0b:	c7 45 c0 00 10 00 00 	movl   $0x1000,-0x40(%ebp)
c0103a12:	b8 70 71 12 c0       	mov    $0xc0127170,%eax
c0103a17:	8d 50 ff             	lea    -0x1(%eax),%edx
c0103a1a:	8b 45 c0             	mov    -0x40(%ebp),%eax
c0103a1d:	01 d0                	add    %edx,%eax
c0103a1f:	89 45 bc             	mov    %eax,-0x44(%ebp)
c0103a22:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0103a25:	ba 00 00 00 00       	mov    $0x0,%edx
c0103a2a:	f7 75 c0             	divl   -0x40(%ebp)
c0103a2d:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0103a30:	29 d0                	sub    %edx,%eax
c0103a32:	a3 78 70 12 c0       	mov    %eax,0xc0127078

    for (i = 0; i < npage; i ++) {// 遍历每一页
c0103a37:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c0103a3e:	eb 27                	jmp    c0103a67 <page_init+0x1f3>
        SetPageReserved(pages + i);// 将每一页标记为保留状态
c0103a40:	a1 78 70 12 c0       	mov    0xc0127078,%eax
c0103a45:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103a48:	c1 e2 05             	shl    $0x5,%edx
c0103a4b:	01 d0                	add    %edx,%eax
c0103a4d:	83 c0 04             	add    $0x4,%eax
c0103a50:	c7 45 94 00 00 00 00 	movl   $0x0,-0x6c(%ebp)
c0103a57:	89 45 90             	mov    %eax,-0x70(%ebp)
 * Note that @nr may be almost arbitrarily large; this function is not
 * restricted to acting on a single-word quantity.
 * */
static inline void
set_bit(int nr, volatile void *addr) {
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0103a5a:	8b 45 90             	mov    -0x70(%ebp),%eax
c0103a5d:	8b 55 94             	mov    -0x6c(%ebp),%edx
c0103a60:	0f ab 10             	bts    %edx,(%eax)
}
c0103a63:	90                   	nop
    for (i = 0; i < npage; i ++) {// 遍历每一页
c0103a64:	ff 45 dc             	incl   -0x24(%ebp)
c0103a67:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103a6a:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c0103a6f:	39 c2                	cmp    %eax,%edx
c0103a71:	72 cd                	jb     c0103a40 <page_init+0x1cc>
    }

    uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址
c0103a73:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c0103a78:	c1 e0 05             	shl    $0x5,%eax
c0103a7b:	89 c2                	mov    %eax,%edx
c0103a7d:	a1 78 70 12 c0       	mov    0xc0127078,%eax
c0103a82:	01 d0                	add    %edx,%eax
c0103a84:	89 45 b8             	mov    %eax,-0x48(%ebp)
c0103a87:	81 7d b8 ff ff ff bf 	cmpl   $0xbfffffff,-0x48(%ebp)
c0103a8e:	77 23                	ja     c0103ab3 <page_init+0x23f>
c0103a90:	8b 45 b8             	mov    -0x48(%ebp),%eax
c0103a93:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0103a97:	c7 44 24 08 44 99 10 	movl   $0xc0109944,0x8(%esp)
c0103a9e:	c0 
c0103a9f:	c7 44 24 04 18 01 00 	movl   $0x118,0x4(%esp)
c0103aa6:	00 
c0103aa7:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0103aae:	e8 92 c9 ff ff       	call   c0100445 <__panic>
c0103ab3:	8b 45 b8             	mov    -0x48(%ebp),%eax
c0103ab6:	05 00 00 00 40       	add    $0x40000000,%eax
c0103abb:	89 45 b4             	mov    %eax,-0x4c(%ebp)

    for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射
c0103abe:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c0103ac5:	e9 4b 01 00 00       	jmp    c0103c15 <page_init+0x3a1>
        uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址
c0103aca:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0103acd:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103ad0:	89 d0                	mov    %edx,%eax
c0103ad2:	c1 e0 02             	shl    $0x2,%eax
c0103ad5:	01 d0                	add    %edx,%eax
c0103ad7:	c1 e0 02             	shl    $0x2,%eax
c0103ada:	01 c8                	add    %ecx,%eax
c0103adc:	8b 50 08             	mov    0x8(%eax),%edx
c0103adf:	8b 40 04             	mov    0x4(%eax),%eax
c0103ae2:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0103ae5:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0103ae8:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0103aeb:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103aee:	89 d0                	mov    %edx,%eax
c0103af0:	c1 e0 02             	shl    $0x2,%eax
c0103af3:	01 d0                	add    %edx,%eax
c0103af5:	c1 e0 02             	shl    $0x2,%eax
c0103af8:	01 c8                	add    %ecx,%eax
c0103afa:	8b 48 0c             	mov    0xc(%eax),%ecx
c0103afd:	8b 58 10             	mov    0x10(%eax),%ebx
c0103b00:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0103b03:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0103b06:	01 c8                	add    %ecx,%eax
c0103b08:	11 da                	adc    %ebx,%edx
c0103b0a:	89 45 c8             	mov    %eax,-0x38(%ebp)
c0103b0d:	89 55 cc             	mov    %edx,-0x34(%ebp)
        if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存
c0103b10:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0103b13:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103b16:	89 d0                	mov    %edx,%eax
c0103b18:	c1 e0 02             	shl    $0x2,%eax
c0103b1b:	01 d0                	add    %edx,%eax
c0103b1d:	c1 e0 02             	shl    $0x2,%eax
c0103b20:	01 c8                	add    %ecx,%eax
c0103b22:	83 c0 14             	add    $0x14,%eax
c0103b25:	8b 00                	mov    (%eax),%eax
c0103b27:	83 f8 01             	cmp    $0x1,%eax
c0103b2a:	0f 85 e2 00 00 00    	jne    c0103c12 <page_init+0x39e>
            if (begin < freemem) {// 如果起始地址小于可用内存地址
c0103b30:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0103b33:	ba 00 00 00 00       	mov    $0x0,%edx
c0103b38:	8b 4d d4             	mov    -0x2c(%ebp),%ecx
c0103b3b:	39 45 d0             	cmp    %eax,-0x30(%ebp)
c0103b3e:	19 d1                	sbb    %edx,%ecx
c0103b40:	73 0d                	jae    c0103b4f <page_init+0x2db>
                begin = freemem;//将起始地址设置为可用内存地址
c0103b42:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0103b45:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0103b48:	c7 45 d4 00 00 00 00 	movl   $0x0,-0x2c(%ebp)
            }
            if (end > KMEMSIZE) {// 如果结束地址超过内存上限
c0103b4f:	ba 00 00 00 38       	mov    $0x38000000,%edx
c0103b54:	b8 00 00 00 00       	mov    $0x0,%eax
c0103b59:	3b 55 c8             	cmp    -0x38(%ebp),%edx
c0103b5c:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c0103b5f:	73 0e                	jae    c0103b6f <page_init+0x2fb>
                end = KMEMSIZE;// 将其限制为内存上限
c0103b61:	c7 45 c8 00 00 00 38 	movl   $0x38000000,-0x38(%ebp)
c0103b68:	c7 45 cc 00 00 00 00 	movl   $0x0,-0x34(%ebp)
            }
            if (begin < end) {// 如果起始地址小于结束地址
c0103b6f:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0103b72:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0103b75:	3b 45 c8             	cmp    -0x38(%ebp),%eax
c0103b78:	89 d0                	mov    %edx,%eax
c0103b7a:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c0103b7d:	0f 83 8f 00 00 00    	jae    c0103c12 <page_init+0x39e>
                begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界
c0103b83:	c7 45 b0 00 10 00 00 	movl   $0x1000,-0x50(%ebp)
c0103b8a:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0103b8d:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0103b90:	01 d0                	add    %edx,%eax
c0103b92:	48                   	dec    %eax
c0103b93:	89 45 ac             	mov    %eax,-0x54(%ebp)
c0103b96:	8b 45 ac             	mov    -0x54(%ebp),%eax
c0103b99:	ba 00 00 00 00       	mov    $0x0,%edx
c0103b9e:	f7 75 b0             	divl   -0x50(%ebp)
c0103ba1:	8b 45 ac             	mov    -0x54(%ebp),%eax
c0103ba4:	29 d0                	sub    %edx,%eax
c0103ba6:	ba 00 00 00 00       	mov    $0x0,%edx
c0103bab:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0103bae:	89 55 d4             	mov    %edx,-0x2c(%ebp)
                end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界
c0103bb1:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0103bb4:	89 45 a8             	mov    %eax,-0x58(%ebp)
c0103bb7:	8b 45 a8             	mov    -0x58(%ebp),%eax
c0103bba:	ba 00 00 00 00       	mov    $0x0,%edx
c0103bbf:	89 c3                	mov    %eax,%ebx
c0103bc1:	81 e3 00 f0 ff ff    	and    $0xfffff000,%ebx
c0103bc7:	89 de                	mov    %ebx,%esi
c0103bc9:	89 d0                	mov    %edx,%eax
c0103bcb:	83 e0 00             	and    $0x0,%eax
c0103bce:	89 c7                	mov    %eax,%edi
c0103bd0:	89 75 c8             	mov    %esi,-0x38(%ebp)
c0103bd3:	89 7d cc             	mov    %edi,-0x34(%ebp)
                if (begin < end) {// 如果调整后的起始地址仍小于结束地址
c0103bd6:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0103bd9:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0103bdc:	3b 45 c8             	cmp    -0x38(%ebp),%eax
c0103bdf:	89 d0                	mov    %edx,%eax
c0103be1:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c0103be4:	73 2c                	jae    c0103c12 <page_init+0x39e>
                    init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射
c0103be6:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0103be9:	8b 55 cc             	mov    -0x34(%ebp),%edx
c0103bec:	2b 45 d0             	sub    -0x30(%ebp),%eax
c0103bef:	1b 55 d4             	sbb    -0x2c(%ebp),%edx
c0103bf2:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c0103bf6:	c1 ea 0c             	shr    $0xc,%edx
c0103bf9:	89 c3                	mov    %eax,%ebx
c0103bfb:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0103bfe:	89 04 24             	mov    %eax,(%esp)
c0103c01:	e8 4a f8 ff ff       	call   c0103450 <pa2page>
c0103c06:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c0103c0a:	89 04 24             	mov    %eax,(%esp)
c0103c0d:	e8 69 fb ff ff       	call   c010377b <init_memmap>
    for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射
c0103c12:	ff 45 dc             	incl   -0x24(%ebp)
c0103c15:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0103c18:	8b 00                	mov    (%eax),%eax
c0103c1a:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c0103c1d:	0f 8c a7 fe ff ff    	jl     c0103aca <page_init+0x256>
                }
            }
        }
    }
}
c0103c23:	90                   	nop
c0103c24:	90                   	nop
c0103c25:	81 c4 9c 00 00 00    	add    $0x9c,%esp
c0103c2b:	5b                   	pop    %ebx
c0103c2c:	5e                   	pop    %esi
c0103c2d:	5f                   	pop    %edi
c0103c2e:	5d                   	pop    %ebp
c0103c2f:	c3                   	ret    

c0103c30 <boot_map_segment>:
//la:   需要映射的线性地址（经过 x86 段映射后的地址）
//  size: memory size   size: 内存大小
//  pa:   physical address of this memory  pa:该内存的物理地址
//  perm: permission of this memory    perm: 该内存的权限
static void
boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) {
c0103c30:	f3 0f 1e fb          	endbr32 
c0103c34:	55                   	push   %ebp
c0103c35:	89 e5                	mov    %esp,%ebp
c0103c37:	83 ec 38             	sub    $0x38,%esp
    // 确保线性地址和物理地址的页偏移相同
    assert(PGOFF(la) == PGOFF(pa));
c0103c3a:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103c3d:	33 45 14             	xor    0x14(%ebp),%eax
c0103c40:	25 ff 0f 00 00       	and    $0xfff,%eax
c0103c45:	85 c0                	test   %eax,%eax
c0103c47:	74 24                	je     c0103c6d <boot_map_segment+0x3d>
c0103c49:	c7 44 24 0c f6 99 10 	movl   $0xc01099f6,0xc(%esp)
c0103c50:	c0 
c0103c51:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0103c58:	c0 
c0103c59:	c7 44 24 04 39 01 00 	movl   $0x139,0x4(%esp)
c0103c60:	00 
c0103c61:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0103c68:	e8 d8 c7 ff ff       	call   c0100445 <__panic>
    // 计算需要映射的页数，ROUNDUP 将总大小对齐到下一个页大小的边界
    size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE;
c0103c6d:	c7 45 f0 00 10 00 00 	movl   $0x1000,-0x10(%ebp)
c0103c74:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103c77:	25 ff 0f 00 00       	and    $0xfff,%eax
c0103c7c:	89 c2                	mov    %eax,%edx
c0103c7e:	8b 45 10             	mov    0x10(%ebp),%eax
c0103c81:	01 c2                	add    %eax,%edx
c0103c83:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103c86:	01 d0                	add    %edx,%eax
c0103c88:	48                   	dec    %eax
c0103c89:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0103c8c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103c8f:	ba 00 00 00 00       	mov    $0x0,%edx
c0103c94:	f7 75 f0             	divl   -0x10(%ebp)
c0103c97:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103c9a:	29 d0                	sub    %edx,%eax
c0103c9c:	c1 e8 0c             	shr    $0xc,%eax
c0103c9f:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 将线性地址向下对齐到页边界
    la = ROUNDDOWN(la, PGSIZE);
c0103ca2:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103ca5:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0103ca8:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0103cab:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0103cb0:	89 45 0c             	mov    %eax,0xc(%ebp)
    // 将物理地址向下对齐到页边界
    pa = ROUNDDOWN(pa, PGSIZE);
c0103cb3:	8b 45 14             	mov    0x14(%ebp),%eax
c0103cb6:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0103cb9:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0103cbc:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0103cc1:	89 45 14             	mov    %eax,0x14(%ebp)
    // 循环遍历每一页，直到映射的页数为零
    for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) {
c0103cc4:	eb 68                	jmp    c0103d2e <boot_map_segment+0xfe>
        // 获取当前页的页表项指针，如果不存在则创建新的页表项
        pte_t *ptep = get_pte(pgdir, la, 1);
c0103cc6:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c0103ccd:	00 
c0103cce:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103cd1:	89 44 24 04          	mov    %eax,0x4(%esp)
c0103cd5:	8b 45 08             	mov    0x8(%ebp),%eax
c0103cd8:	89 04 24             	mov    %eax,(%esp)
c0103cdb:	e8 8a 01 00 00       	call   c0103e6a <get_pte>
c0103ce0:	89 45 e0             	mov    %eax,-0x20(%ebp)
        // 确保页表项指针不为空
        assert(ptep != NULL);
c0103ce3:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c0103ce7:	75 24                	jne    c0103d0d <boot_map_segment+0xdd>
c0103ce9:	c7 44 24 0c 22 9a 10 	movl   $0xc0109a22,0xc(%esp)
c0103cf0:	c0 
c0103cf1:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0103cf8:	c0 
c0103cf9:	c7 44 24 04 45 01 00 	movl   $0x145,0x4(%esp)
c0103d00:	00 
c0103d01:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0103d08:	e8 38 c7 ff ff       	call   c0100445 <__panic>
         // 设置页表项，包含物理地址、存在位和权限
        *ptep = pa | PTE_P | perm;
c0103d0d:	8b 45 14             	mov    0x14(%ebp),%eax
c0103d10:	0b 45 18             	or     0x18(%ebp),%eax
c0103d13:	83 c8 01             	or     $0x1,%eax
c0103d16:	89 c2                	mov    %eax,%edx
c0103d18:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0103d1b:	89 10                	mov    %edx,(%eax)
    for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) {
c0103d1d:	ff 4d f4             	decl   -0xc(%ebp)
c0103d20:	81 45 0c 00 10 00 00 	addl   $0x1000,0xc(%ebp)
c0103d27:	81 45 14 00 10 00 00 	addl   $0x1000,0x14(%ebp)
c0103d2e:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0103d32:	75 92                	jne    c0103cc6 <boot_map_segment+0x96>
    }
}
c0103d34:	90                   	nop
c0103d35:	90                   	nop
c0103d36:	c9                   	leave  
c0103d37:	c3                   	ret    

c0103d38 <boot_alloc_page>:
// return value: the kernel virtual address of this allocated page
//note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table)
//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址
//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存
static void *
boot_alloc_page(void) {
c0103d38:	f3 0f 1e fb          	endbr32 
c0103d3c:	55                   	push   %ebp
c0103d3d:	89 e5                	mov    %esp,%ebp
c0103d3f:	83 ec 28             	sub    $0x28,%esp
    struct Page *p = alloc_page();// 调用分配页面的函数
c0103d42:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103d49:	e8 51 fa ff ff       	call   c010379f <alloc_pages>
c0103d4e:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (p == NULL) {// 检查分配是否成功
c0103d51:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0103d55:	75 1c                	jne    c0103d73 <boot_alloc_page+0x3b>
        panic("boot_alloc_page failed.\n");// 如果分配失败，则触发异常
c0103d57:	c7 44 24 08 2f 9a 10 	movl   $0xc0109a2f,0x8(%esp)
c0103d5e:	c0 
c0103d5f:	c7 44 24 04 54 01 00 	movl   $0x154,0x4(%esp)
c0103d66:	00 
c0103d67:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0103d6e:	e8 d2 c6 ff ff       	call   c0100445 <__panic>
    }
    return page2kva(p);// 返回分配页面的内核虚拟地址
c0103d73:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103d76:	89 04 24             	mov    %eax,(%esp)
c0103d79:	e8 17 f7 ff ff       	call   c0103495 <page2kva>
}
c0103d7e:	c9                   	leave  
c0103d7f:	c3                   	ret    

c0103d80 <pmm_init>:
//pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism 
//         - check the correctness of pmm & paging mechanism, print PDT&PT
//pmm_init - 设置物理内存管理器，构建页目录表(PDT)和页表(PT)，以设置分页机制
//           - 检查物理内存管理器和分页机制的正确性，打印页目录表和页表
void
pmm_init(void) {
c0103d80:	f3 0f 1e fb          	endbr32 
c0103d84:	55                   	push   %ebp
c0103d85:	89 e5                	mov    %esp,%ebp
c0103d87:	83 ec 38             	sub    $0x38,%esp
    // We've already enabled paging
    // 我们已经启用了分页
    boot_cr3 = PADDR(boot_pgdir);
c0103d8a:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0103d8f:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0103d92:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c0103d99:	77 23                	ja     c0103dbe <pmm_init+0x3e>
c0103d9b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103d9e:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0103da2:	c7 44 24 08 44 99 10 	movl   $0xc0109944,0x8(%esp)
c0103da9:	c0 
c0103daa:	c7 44 24 04 61 01 00 	movl   $0x161,0x4(%esp)
c0103db1:	00 
c0103db2:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0103db9:	e8 87 c6 ff ff       	call   c0100445 <__panic>
c0103dbe:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103dc1:	05 00 00 00 40       	add    $0x40000000,%eax
c0103dc6:	a3 74 70 12 c0       	mov    %eax,0xc0127074
     // 我们需要分配/释放物理内存（粒度为 4KB 或其他大小）。
    // 因此在 pmm.h 中定义了物理内存管理器的框架（struct pmm_manager）。
    // 首先，我们应该基于该框架初始化一个物理内存管理器(pmm)。
    // 然后 pmm 可以分配/释放物理内存。
    // 现在，first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。
    init_pmm_manager();// 初始化物理内存管理器
c0103dcb:	e8 73 f9 ff ff       	call   c0103743 <init_pmm_manager>

    // detect physical memory space, reserve already used memory,
    // then use pmm->init_memmap to create free page list
    // 检测物理内存空间，保留已经使用的内存，
    // 然后使用 pmm->init_memmap 创建空闲页面列表
    page_init();// 初始化页面管理
c0103dd0:	e8 9f fa ff ff       	call   c0103874 <page_init>

    //use pmm->check to verify the correctness of the alloc/free function in a pmm
    // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性
    check_alloc_page();// 检查页面分配功能
c0103dd5:	e8 c2 04 00 00       	call   c010429c <check_alloc_page>

    check_pgdir();// 检查页目录的状态
c0103dda:	e8 e0 04 00 00       	call   c01042bf <check_pgdir>

    // recursively insert boot_pgdir in itself
    // to form a virtual page table at virtual address VPT
    // 递归地将 boot_pgdir 插入到自身中
    // 在虚拟地址 VPT 处形成虚拟页表
    boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项，映射自身
c0103ddf:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0103de4:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103de7:	81 7d f0 ff ff ff bf 	cmpl   $0xbfffffff,-0x10(%ebp)
c0103dee:	77 23                	ja     c0103e13 <pmm_init+0x93>
c0103df0:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103df3:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0103df7:	c7 44 24 08 44 99 10 	movl   $0xc0109944,0x8(%esp)
c0103dfe:	c0 
c0103dff:	c7 44 24 04 81 01 00 	movl   $0x181,0x4(%esp)
c0103e06:	00 
c0103e07:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0103e0e:	e8 32 c6 ff ff       	call   c0100445 <__panic>
c0103e13:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103e16:	8d 90 00 00 00 40    	lea    0x40000000(%eax),%edx
c0103e1c:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0103e21:	05 ac 0f 00 00       	add    $0xfac,%eax
c0103e26:	83 ca 03             	or     $0x3,%edx
c0103e29:	89 10                	mov    %edx,(%eax)

    // map all physical memory to linear memory with base linear addr KERNBASE
    // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE
    // 将所有物理内存映射到线性内存，基地址为 KERNBASE
    // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE
    boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存
c0103e2b:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0103e30:	c7 44 24 10 02 00 00 	movl   $0x2,0x10(%esp)
c0103e37:	00 
c0103e38:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0103e3f:	00 
c0103e40:	c7 44 24 08 00 00 00 	movl   $0x38000000,0x8(%esp)
c0103e47:	38 
c0103e48:	c7 44 24 04 00 00 00 	movl   $0xc0000000,0x4(%esp)
c0103e4f:	c0 
c0103e50:	89 04 24             	mov    %eax,(%esp)
c0103e53:	e8 d8 fd ff ff       	call   c0103c30 <boot_map_segment>
    // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS
    // 由于我们正在使用引导加载程序的 GDT，
    // 我们应该重新加载 GDT（第二次，也是最后一次），以获取用户段和 TSS
    // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G
    // 然后在 TSS 中设置内核栈 (ss:esp)，在 gdt 中设置 TSS，加载 TSS
    gdt_init();// 初始化全局描述符表
c0103e58:	e8 f8 f7 ff ff       	call   c0103655 <gdt_init>

    //now the basic virtual memory map(see memalyout.h) is established.
    //check the correctness of the basic virtual memory map.
     // 现在基本的虚拟内存映射（见 memlayout.h）已建立。
    // 检查基础虚拟内存映射的正确性。
    check_boot_pgdir(); // 检查页目录的正确性
c0103e5d:	e8 fd 0a 00 00       	call   c010495f <check_boot_pgdir>

    print_pgdir(); // 打印页目录表
c0103e62:	e8 82 0f 00 00       	call   c0104de9 <print_pgdir>

}
c0103e67:	90                   	nop
c0103e68:	c9                   	leave  
c0103e69:	c3                   	ret    

c0103e6a <get_pte>:
//  pgdir:  页目录的内核虚拟基地址
//  la:     需要映射的线性地址
//  create: 一个逻辑值，决定是否为页表分配一页
// 返回值：该 PTE 的内核虚拟地址
pte_t *
get_pte(pde_t *pgdir, uintptr_t la, bool create) {
c0103e6a:	f3 0f 1e fb          	endbr32 
c0103e6e:	55                   	push   %ebp
c0103e6f:	89 e5                	mov    %esp,%ebp
c0103e71:	83 ec 38             	sub    $0x38,%esp
                          // (7) set page directory entry's permission
    }
    return NULL;          // (8) return page table entry
#endif
    // (1) 找到页目录项
    pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引
c0103e74:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103e77:	c1 e8 16             	shr    $0x16,%eax
c0103e7a:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0103e81:	8b 45 08             	mov    0x8(%ebp),%eax
c0103e84:	01 d0                	add    %edx,%eax
c0103e86:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // (2) 检查页目录项是否存在
    if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置
c0103e89:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103e8c:	8b 00                	mov    (%eax),%eax
c0103e8e:	83 e0 01             	and    $0x1,%eax
c0103e91:	85 c0                	test   %eax,%eax
c0103e93:	0f 85 af 00 00 00    	jne    c0103f48 <get_pte+0xde>
        struct Page *page;// 声明一个指针，用于指向新分配的页面
        // 检查是否允许创建新页表，或者分配页表失败
        if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败
c0103e99:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0103e9d:	74 15                	je     c0103eb4 <get_pte+0x4a>
c0103e9f:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103ea6:	e8 f4 f8 ff ff       	call   c010379f <alloc_pages>
c0103eab:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103eae:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0103eb2:	75 0a                	jne    c0103ebe <get_pte+0x54>
            return NULL;// 返回 NULL，表示无法获取页表
c0103eb4:	b8 00 00 00 00       	mov    $0x0,%eax
c0103eb9:	e9 e7 00 00 00       	jmp    c0103fa5 <get_pte+0x13b>
        }
        // 设置新分配页面的引用计数为 1
        set_page_ref(page, 1);
c0103ebe:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103ec5:	00 
c0103ec6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103ec9:	89 04 24             	mov    %eax,(%esp)
c0103ecc:	e8 c2 f6 ff ff       	call   c0103593 <set_page_ref>
        uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址
c0103ed1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103ed4:	89 04 24             	mov    %eax,(%esp)
c0103ed7:	e8 5e f5 ff ff       	call   c010343a <page2pa>
c0103edc:	89 45 ec             	mov    %eax,-0x14(%ebp)
        memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容，初始化为零
c0103edf:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103ee2:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0103ee5:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0103ee8:	c1 e8 0c             	shr    $0xc,%eax
c0103eeb:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0103eee:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c0103ef3:	39 45 e4             	cmp    %eax,-0x1c(%ebp)
c0103ef6:	72 23                	jb     c0103f1b <get_pte+0xb1>
c0103ef8:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0103efb:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0103eff:	c7 44 24 08 20 99 10 	movl   $0xc0109920,0x8(%esp)
c0103f06:	c0 
c0103f07:	c7 44 24 04 da 01 00 	movl   $0x1da,0x4(%esp)
c0103f0e:	00 
c0103f0f:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0103f16:	e8 2a c5 ff ff       	call   c0100445 <__panic>
c0103f1b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0103f1e:	2d 00 00 00 40       	sub    $0x40000000,%eax
c0103f23:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0103f2a:	00 
c0103f2b:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0103f32:	00 
c0103f33:	89 04 24             	mov    %eax,(%esp)
c0103f36:	e8 b2 47 00 00       	call   c01086ed <memset>
        // 更新页目录项，设置物理地址和权限位
        *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位（用户可访问、可写、有效）合并设置
c0103f3b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103f3e:	83 c8 07             	or     $0x7,%eax
c0103f41:	89 c2                	mov    %eax,%edx
c0103f43:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103f46:	89 10                	mov    %edx,(%eax)
    }
    // 返回指定线性地址 la 对应的页表项的内核虚拟地址
    return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针
c0103f48:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103f4b:	8b 00                	mov    (%eax),%eax
c0103f4d:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0103f52:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0103f55:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0103f58:	c1 e8 0c             	shr    $0xc,%eax
c0103f5b:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0103f5e:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c0103f63:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c0103f66:	72 23                	jb     c0103f8b <get_pte+0x121>
c0103f68:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0103f6b:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0103f6f:	c7 44 24 08 20 99 10 	movl   $0xc0109920,0x8(%esp)
c0103f76:	c0 
c0103f77:	c7 44 24 04 df 01 00 	movl   $0x1df,0x4(%esp)
c0103f7e:	00 
c0103f7f:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0103f86:	e8 ba c4 ff ff       	call   c0100445 <__panic>
c0103f8b:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0103f8e:	2d 00 00 00 40       	sub    $0x40000000,%eax
c0103f93:	89 c2                	mov    %eax,%edx
c0103f95:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103f98:	c1 e8 0c             	shr    $0xc,%eax
c0103f9b:	25 ff 03 00 00       	and    $0x3ff,%eax
c0103fa0:	c1 e0 02             	shl    $0x2,%eax
c0103fa3:	01 d0                	add    %edx,%eax
}
c0103fa5:	c9                   	leave  
c0103fa6:	c3                   	ret    

c0103fa7 <get_page>:

//get_page - get related Page struct for linear address la using PDT pgdir
// get_page - 获取与线性地址 la 相关的 Page 结构体，使用页目录 pgdir
struct Page *
get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) {
c0103fa7:	f3 0f 1e fb          	endbr32 
c0103fab:	55                   	push   %ebp
c0103fac:	89 e5                	mov    %esp,%ebp
c0103fae:	83 ec 28             	sub    $0x28,%esp
     // 调用 get_pte 函数获取对应线性地址 la 的页表项指针
    pte_t *ptep = get_pte(pgdir, la, 0);
c0103fb1:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0103fb8:	00 
c0103fb9:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103fbc:	89 44 24 04          	mov    %eax,0x4(%esp)
c0103fc0:	8b 45 08             	mov    0x8(%ebp),%eax
c0103fc3:	89 04 24             	mov    %eax,(%esp)
c0103fc6:	e8 9f fe ff ff       	call   c0103e6a <get_pte>
c0103fcb:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 如果 ptep_store 指针不为 NULL，将 ptep 存储到 ptep_store 指向的位置
    if (ptep_store != NULL) {
c0103fce:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0103fd2:	74 08                	je     c0103fdc <get_page+0x35>
        *ptep_store = ptep; // 存储当前页表项的指针
c0103fd4:	8b 45 10             	mov    0x10(%ebp),%eax
c0103fd7:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0103fda:	89 10                	mov    %edx,(%eax)
    }
    // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置
    if (ptep != NULL && *ptep & PTE_P) {
c0103fdc:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0103fe0:	74 1b                	je     c0103ffd <get_page+0x56>
c0103fe2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103fe5:	8b 00                	mov    (%eax),%eax
c0103fe7:	83 e0 01             	and    $0x1,%eax
c0103fea:	85 c0                	test   %eax,%eax
c0103fec:	74 0f                	je     c0103ffd <get_page+0x56>
        // 返回与页表项对应的 Page 结构体
        return pte2page(*ptep);// 将页表项转换为对应的 Page 结构
c0103fee:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103ff1:	8b 00                	mov    (%eax),%eax
c0103ff3:	89 04 24             	mov    %eax,(%esp)
c0103ff6:	e8 38 f5 ff ff       	call   c0103533 <pte2page>
c0103ffb:	eb 05                	jmp    c0104002 <get_page+0x5b>
    }
    // 如果未找到有效的页，返回 NULL
    return NULL;
c0103ffd:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104002:	c9                   	leave  
c0104003:	c3                   	ret    

c0104004 <page_remove_pte>:

//page_remove_pte - free an Page sturct which is related linear address la
//                - and clean(invalidate) pte which is related linear address la
//note: PT is changed, so the TLB need to be invalidate 
static inline void
page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) {
c0104004:	55                   	push   %ebp
c0104005:	89 e5                	mov    %esp,%ebp
c0104007:	83 ec 28             	sub    $0x28,%esp
                                  //(4) and free this page when page reference reachs 0
                                  //(5) clear second page table entry
                                  //(6) flush tlb
    }
#endif
    if (*ptep & PTE_P) {
c010400a:	8b 45 10             	mov    0x10(%ebp),%eax
c010400d:	8b 00                	mov    (%eax),%eax
c010400f:	83 e0 01             	and    $0x1,%eax
c0104012:	85 c0                	test   %eax,%eax
c0104014:	74 4d                	je     c0104063 <page_remove_pte+0x5f>
        struct Page *page = pte2page(*ptep);// 找到对应的物理页
c0104016:	8b 45 10             	mov    0x10(%ebp),%eax
c0104019:	8b 00                	mov    (%eax),%eax
c010401b:	89 04 24             	mov    %eax,(%esp)
c010401e:	e8 10 f5 ff ff       	call   c0103533 <pte2page>
c0104023:	89 45 f4             	mov    %eax,-0xc(%ebp)
        // 减少物理页的引用计数，如果引用计数为零，释放该物理页
        if (page_ref_dec(page) == 0) {
c0104026:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104029:	89 04 24             	mov    %eax,(%esp)
c010402c:	e8 87 f5 ff ff       	call   c01035b8 <page_ref_dec>
c0104031:	85 c0                	test   %eax,%eax
c0104033:	75 13                	jne    c0104048 <page_remove_pte+0x44>
            free_page(page);
c0104035:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010403c:	00 
c010403d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104040:	89 04 24             	mov    %eax,(%esp)
c0104043:	e8 c6 f7 ff ff       	call   c010380e <free_pages>
        }
        *ptep = 0;// 清除页表项
c0104048:	8b 45 10             	mov    0x10(%ebp),%eax
c010404b:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
        tlb_invalidate(pgdir, la);// 刷新 TLB
c0104051:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104054:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104058:	8b 45 08             	mov    0x8(%ebp),%eax
c010405b:	89 04 24             	mov    %eax,(%esp)
c010405e:	e8 09 01 00 00       	call   c010416c <tlb_invalidate>
    }
}
c0104063:	90                   	nop
c0104064:	c9                   	leave  
c0104065:	c3                   	ret    

c0104066 <page_remove>:

//page_remove - free an Page which is related linear address la and has an validated pte
//移除一个虚拟地址对应的页面
void
page_remove(pde_t *pgdir, uintptr_t la) {
c0104066:	f3 0f 1e fb          	endbr32 
c010406a:	55                   	push   %ebp
c010406b:	89 e5                	mov    %esp,%ebp
c010406d:	83 ec 28             	sub    $0x28,%esp
    //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。
    pte_t *ptep = get_pte(pgdir, la, 0);
c0104070:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0104077:	00 
c0104078:	8b 45 0c             	mov    0xc(%ebp),%eax
c010407b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010407f:	8b 45 08             	mov    0x8(%ebp),%eax
c0104082:	89 04 24             	mov    %eax,(%esp)
c0104085:	e8 e0 fd ff ff       	call   c0103e6a <get_pte>
c010408a:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //如果 ptep 不为 NULL，则调用 page_remove_pte 函数移除该页表项。
    if (ptep != NULL) {
c010408d:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104091:	74 19                	je     c01040ac <page_remove+0x46>
        page_remove_pte(pgdir, la, ptep);
c0104093:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104096:	89 44 24 08          	mov    %eax,0x8(%esp)
c010409a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010409d:	89 44 24 04          	mov    %eax,0x4(%esp)
c01040a1:	8b 45 08             	mov    0x8(%ebp),%eax
c01040a4:	89 04 24             	mov    %eax,(%esp)
c01040a7:	e8 58 ff ff ff       	call   c0104004 <page_remove_pte>
    }
}
c01040ac:	90                   	nop
c01040ad:	c9                   	leave  
c01040ae:	c3                   	ret    

c01040af <page_insert>:
//  perm:  the permission of this Page which is setted in related pte
// return value: always 0
//note: PT is changed, so the TLB need to be invalidate 
//将一个页面插入到页表中。
int
page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) {
c01040af:	f3 0f 1e fb          	endbr32 
c01040b3:	55                   	push   %ebp
c01040b4:	89 e5                	mov    %esp,%ebp
c01040b6:	83 ec 28             	sub    $0x28,%esp
    //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。
    pte_t *ptep = get_pte(pgdir, la, 1);
c01040b9:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c01040c0:	00 
c01040c1:	8b 45 10             	mov    0x10(%ebp),%eax
c01040c4:	89 44 24 04          	mov    %eax,0x4(%esp)
c01040c8:	8b 45 08             	mov    0x8(%ebp),%eax
c01040cb:	89 04 24             	mov    %eax,(%esp)
c01040ce:	e8 97 fd ff ff       	call   c0103e6a <get_pte>
c01040d3:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //如果 ptep 为 NULL，表示内存分配失败，返回 -E_NO_MEM。
    if (ptep == NULL) {
c01040d6:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01040da:	75 0a                	jne    c01040e6 <page_insert+0x37>
        return -E_NO_MEM;
c01040dc:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
c01040e1:	e9 84 00 00 00       	jmp    c010416a <page_insert+0xbb>
    }
    //调用 page_ref_inc 增加页面的引用计数。
    page_ref_inc(page);
c01040e6:	8b 45 0c             	mov    0xc(%ebp),%eax
c01040e9:	89 04 24             	mov    %eax,(%esp)
c01040ec:	e8 b0 f4 ff ff       	call   c01035a1 <page_ref_inc>
    //如果页表项已存在且指向当前页面，则减少页面引用计数。
    if (*ptep & PTE_P) {
c01040f1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01040f4:	8b 00                	mov    (%eax),%eax
c01040f6:	83 e0 01             	and    $0x1,%eax
c01040f9:	85 c0                	test   %eax,%eax
c01040fb:	74 3e                	je     c010413b <page_insert+0x8c>
        struct Page *p = pte2page(*ptep);
c01040fd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104100:	8b 00                	mov    (%eax),%eax
c0104102:	89 04 24             	mov    %eax,(%esp)
c0104105:	e8 29 f4 ff ff       	call   c0103533 <pte2page>
c010410a:	89 45 f0             	mov    %eax,-0x10(%ebp)
        if (p == page) {
c010410d:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104110:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0104113:	75 0d                	jne    c0104122 <page_insert+0x73>
            page_ref_dec(page);
c0104115:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104118:	89 04 24             	mov    %eax,(%esp)
c010411b:	e8 98 f4 ff ff       	call   c01035b8 <page_ref_dec>
c0104120:	eb 19                	jmp    c010413b <page_insert+0x8c>
        }
        //如果页表项已存在但指向其他页面，则调用 page_remove_pte 移除旧的页表项。
        else {
            page_remove_pte(pgdir, la, ptep);
c0104122:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104125:	89 44 24 08          	mov    %eax,0x8(%esp)
c0104129:	8b 45 10             	mov    0x10(%ebp),%eax
c010412c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104130:	8b 45 08             	mov    0x8(%ebp),%eax
c0104133:	89 04 24             	mov    %eax,(%esp)
c0104136:	e8 c9 fe ff ff       	call   c0104004 <page_remove_pte>
        }
    }
    *ptep = page2pa(page) | PTE_P | perm;
c010413b:	8b 45 0c             	mov    0xc(%ebp),%eax
c010413e:	89 04 24             	mov    %eax,(%esp)
c0104141:	e8 f4 f2 ff ff       	call   c010343a <page2pa>
c0104146:	0b 45 14             	or     0x14(%ebp),%eax
c0104149:	83 c8 01             	or     $0x1,%eax
c010414c:	89 c2                	mov    %eax,%edx
c010414e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104151:	89 10                	mov    %edx,(%eax)
    tlb_invalidate(pgdir, la);//刷新 TLB
c0104153:	8b 45 10             	mov    0x10(%ebp),%eax
c0104156:	89 44 24 04          	mov    %eax,0x4(%esp)
c010415a:	8b 45 08             	mov    0x8(%ebp),%eax
c010415d:	89 04 24             	mov    %eax,(%esp)
c0104160:	e8 07 00 00 00       	call   c010416c <tlb_invalidate>
    return 0;
c0104165:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010416a:	c9                   	leave  
c010416b:	c3                   	ret    

c010416c <tlb_invalidate>:

// invalidate a TLB entry, but only if the page tables being
// edited are the ones currently in use by the processor.
//无效化指定地址的TLB条目
void
tlb_invalidate(pde_t *pgdir, uintptr_t la) {
c010416c:	f3 0f 1e fb          	endbr32 
c0104170:	55                   	push   %ebp
c0104171:	89 e5                	mov    %esp,%ebp
c0104173:	83 ec 28             	sub    $0x28,%esp
}

static inline uintptr_t
rcr3(void) {
    uintptr_t cr3;
    asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory");
c0104176:	0f 20 d8             	mov    %cr3,%eax
c0104179:	89 45 f0             	mov    %eax,-0x10(%ebp)
    return cr3;
c010417c:	8b 55 f0             	mov    -0x10(%ebp),%edx
    //检查当前页目录地址是否与传入的页目录地址相同。
    if (rcr3() == PADDR(pgdir)) {
c010417f:	8b 45 08             	mov    0x8(%ebp),%eax
c0104182:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104185:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c010418c:	77 23                	ja     c01041b1 <tlb_invalidate+0x45>
c010418e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104191:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0104195:	c7 44 24 08 44 99 10 	movl   $0xc0109944,0x8(%esp)
c010419c:	c0 
c010419d:	c7 44 24 04 53 02 00 	movl   $0x253,0x4(%esp)
c01041a4:	00 
c01041a5:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01041ac:	e8 94 c2 ff ff       	call   c0100445 <__panic>
c01041b1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01041b4:	05 00 00 00 40       	add    $0x40000000,%eax
c01041b9:	39 d0                	cmp    %edx,%eax
c01041bb:	75 0d                	jne    c01041ca <tlb_invalidate+0x5e>
        //如果相同，则调用 invlpg 函数无效化指定线性地址的TLB条目。
        invlpg((void *)la);
c01041bd:	8b 45 0c             	mov    0xc(%ebp),%eax
c01041c0:	89 45 ec             	mov    %eax,-0x14(%ebp)
}

static inline void
invlpg(void *addr) {
    asm volatile ("invlpg (%0)" :: "r" (addr) : "memory");
c01041c3:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01041c6:	0f 01 38             	invlpg (%eax)
}
c01041c9:	90                   	nop
    }
}
c01041ca:	90                   	nop
c01041cb:	c9                   	leave  
c01041cc:	c3                   	ret    

c01041cd <pgdir_alloc_page>:
// pgdir_alloc_page - call alloc_page & page_insert functions to 
//                  - allocate a page size memory & setup an addr map
//                  - pa<->la with linear address la and the PDT pgdir
//参数包括页目录指针 pgdir、线性地址 la 和权限 perm。
struct Page *
pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm) {
c01041cd:	f3 0f 1e fb          	endbr32 
c01041d1:	55                   	push   %ebp
c01041d2:	89 e5                	mov    %esp,%ebp
c01041d4:	83 ec 28             	sub    $0x28,%esp
    struct Page *page = alloc_page();//分配一个新的页面存储在 page 指针中
c01041d7:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01041de:	e8 bc f5 ff ff       	call   c010379f <alloc_pages>
c01041e3:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (page != NULL) {//检查 page 是否不为 NULL，即分配是否成功。
c01041e6:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01041ea:	0f 84 a7 00 00 00    	je     c0104297 <pgdir_alloc_page+0xca>
        if (page_insert(pgdir, page, la, perm) != 0) {//将页面插入到指定的线性地址 la 处。
c01041f0:	8b 45 10             	mov    0x10(%ebp),%eax
c01041f3:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01041f7:	8b 45 0c             	mov    0xc(%ebp),%eax
c01041fa:	89 44 24 08          	mov    %eax,0x8(%esp)
c01041fe:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104201:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104205:	8b 45 08             	mov    0x8(%ebp),%eax
c0104208:	89 04 24             	mov    %eax,(%esp)
c010420b:	e8 9f fe ff ff       	call   c01040af <page_insert>
c0104210:	85 c0                	test   %eax,%eax
c0104212:	74 1a                	je     c010422e <pgdir_alloc_page+0x61>
            free_page(page);//释放分配的页面。
c0104214:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010421b:	00 
c010421c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010421f:	89 04 24             	mov    %eax,(%esp)
c0104222:	e8 e7 f5 ff ff       	call   c010380e <free_pages>
            return NULL;//返回 NULL，表示页面插入失败。
c0104227:	b8 00 00 00 00       	mov    $0x0,%eax
c010422c:	eb 6c                	jmp    c010429a <pgdir_alloc_page+0xcd>
        }
        if (swap_init_ok){//检查交换区是否已初始化成功
c010422e:	a1 10 70 12 c0       	mov    0xc0127010,%eax
c0104233:	85 c0                	test   %eax,%eax
c0104235:	74 60                	je     c0104297 <pgdir_alloc_page+0xca>
            //将页面映射到交换区。
            swap_map_swappable(check_mm_struct, la, page, 0);
c0104237:	a1 84 70 12 c0       	mov    0xc0127084,%eax
c010423c:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0104243:	00 
c0104244:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0104247:	89 54 24 08          	mov    %edx,0x8(%esp)
c010424b:	8b 55 0c             	mov    0xc(%ebp),%edx
c010424e:	89 54 24 04          	mov    %edx,0x4(%esp)
c0104252:	89 04 24             	mov    %eax,(%esp)
c0104255:	e8 bd 22 00 00       	call   c0106517 <swap_map_swappable>
            //设置页面的虚拟地址 pra_vaddr 为 la
            page->pra_vaddr=la;
c010425a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010425d:	8b 55 0c             	mov    0xc(%ebp),%edx
c0104260:	89 50 1c             	mov    %edx,0x1c(%eax)
            //断言页面的引用计数为1，确保页面没有被其他地方引用。
            assert(page_ref(page) == 1);
c0104263:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104266:	89 04 24             	mov    %eax,(%esp)
c0104269:	e8 1b f3 ff ff       	call   c0103589 <page_ref>
c010426e:	83 f8 01             	cmp    $0x1,%eax
c0104271:	74 24                	je     c0104297 <pgdir_alloc_page+0xca>
c0104273:	c7 44 24 0c 48 9a 10 	movl   $0xc0109a48,0xc(%esp)
c010427a:	c0 
c010427b:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104282:	c0 
c0104283:	c7 44 24 04 6b 02 00 	movl   $0x26b,0x4(%esp)
c010428a:	00 
c010428b:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104292:	e8 ae c1 ff ff       	call   c0100445 <__panic>
            //cprintf("get No. %d  page: pra_vaddr %x, pra_link.prev %x, pra_link_next %x in pgdir_alloc_page\n", (page-pages), page->pra_vaddr,page->pra_page_link.prev, page->pra_page_link.next);
        }

    }

    return page;
c0104297:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010429a:	c9                   	leave  
c010429b:	c3                   	ret    

c010429c <check_alloc_page>:

static void
check_alloc_page(void) {
c010429c:	f3 0f 1e fb          	endbr32 
c01042a0:	55                   	push   %ebp
c01042a1:	89 e5                	mov    %esp,%ebp
c01042a3:	83 ec 18             	sub    $0x18,%esp
    //调用内存管理器的 check 方法，用于检查内存分配是否正常。
    pmm_manager->check();
c01042a6:	a1 70 70 12 c0       	mov    0xc0127070,%eax
c01042ab:	8b 40 18             	mov    0x18(%eax),%eax
c01042ae:	ff d0                	call   *%eax
    cprintf("check_alloc_page() succeeded!\n");
c01042b0:	c7 04 24 5c 9a 10 c0 	movl   $0xc0109a5c,(%esp)
c01042b7:	e8 1d c0 ff ff       	call   c01002d9 <cprintf>
}
c01042bc:	90                   	nop
c01042bd:	c9                   	leave  
c01042be:	c3                   	ret    

c01042bf <check_pgdir>:

//用于验证页目录和页表的正确性。
static void
check_pgdir(void) {
c01042bf:	f3 0f 1e fb          	endbr32 
c01042c3:	55                   	push   %ebp
c01042c4:	89 e5                	mov    %esp,%ebp
c01042c6:	83 ec 38             	sub    $0x38,%esp
    //确保内存页面数量在合理范围内
    assert(npage <= KMEMSIZE / PGSIZE);
c01042c9:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c01042ce:	3d 00 80 03 00       	cmp    $0x38000,%eax
c01042d3:	76 24                	jbe    c01042f9 <check_pgdir+0x3a>
c01042d5:	c7 44 24 0c 7b 9a 10 	movl   $0xc0109a7b,0xc(%esp)
c01042dc:	c0 
c01042dd:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01042e4:	c0 
c01042e5:	c7 44 24 04 7f 02 00 	movl   $0x27f,0x4(%esp)
c01042ec:	00 
c01042ed:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01042f4:	e8 4c c1 ff ff       	call   c0100445 <__panic>
    //确保页目录不为空且对齐，
    assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0);
c01042f9:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c01042fe:	85 c0                	test   %eax,%eax
c0104300:	74 0e                	je     c0104310 <check_pgdir+0x51>
c0104302:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104307:	25 ff 0f 00 00       	and    $0xfff,%eax
c010430c:	85 c0                	test   %eax,%eax
c010430e:	74 24                	je     c0104334 <check_pgdir+0x75>
c0104310:	c7 44 24 0c 98 9a 10 	movl   $0xc0109a98,0xc(%esp)
c0104317:	c0 
c0104318:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c010431f:	c0 
c0104320:	c7 44 24 04 81 02 00 	movl   $0x281,0x4(%esp)
c0104327:	00 
c0104328:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c010432f:	e8 11 c1 ff ff       	call   c0100445 <__panic>
    //确保虚拟地址 0x0 没有映射任何页面
    assert(get_page(boot_pgdir, 0x0, NULL) == NULL);
c0104334:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104339:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0104340:	00 
c0104341:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0104348:	00 
c0104349:	89 04 24             	mov    %eax,(%esp)
c010434c:	e8 56 fc ff ff       	call   c0103fa7 <get_page>
c0104351:	85 c0                	test   %eax,%eax
c0104353:	74 24                	je     c0104379 <check_pgdir+0xba>
c0104355:	c7 44 24 0c d0 9a 10 	movl   $0xc0109ad0,0xc(%esp)
c010435c:	c0 
c010435d:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104364:	c0 
c0104365:	c7 44 24 04 83 02 00 	movl   $0x283,0x4(%esp)
c010436c:	00 
c010436d:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104374:	e8 cc c0 ff ff       	call   c0100445 <__panic>
    
    //定义两个页面指针 p1 和 p2
    struct Page *p1, *p2;
    //分配一个页面 p1
    p1 = alloc_page();
c0104379:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0104380:	e8 1a f4 ff ff       	call   c010379f <alloc_pages>
c0104385:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //将 p1 插入到虚拟地址 0x0
    assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0);
c0104388:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c010438d:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0104394:	00 
c0104395:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c010439c:	00 
c010439d:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01043a0:	89 54 24 04          	mov    %edx,0x4(%esp)
c01043a4:	89 04 24             	mov    %eax,(%esp)
c01043a7:	e8 03 fd ff ff       	call   c01040af <page_insert>
c01043ac:	85 c0                	test   %eax,%eax
c01043ae:	74 24                	je     c01043d4 <check_pgdir+0x115>
c01043b0:	c7 44 24 0c f8 9a 10 	movl   $0xc0109af8,0xc(%esp)
c01043b7:	c0 
c01043b8:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01043bf:	c0 
c01043c0:	c7 44 24 04 8a 02 00 	movl   $0x28a,0x4(%esp)
c01043c7:	00 
c01043c8:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01043cf:	e8 71 c0 ff ff       	call   c0100445 <__panic>

    // 获取虚拟地址 0x0 对应的页表项指针
    pte_t *ptep;
    assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL);
c01043d4:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c01043d9:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01043e0:	00 
c01043e1:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01043e8:	00 
c01043e9:	89 04 24             	mov    %eax,(%esp)
c01043ec:	e8 79 fa ff ff       	call   c0103e6a <get_pte>
c01043f1:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01043f4:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01043f8:	75 24                	jne    c010441e <check_pgdir+0x15f>
c01043fa:	c7 44 24 0c 24 9b 10 	movl   $0xc0109b24,0xc(%esp)
c0104401:	c0 
c0104402:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104409:	c0 
c010440a:	c7 44 24 04 8e 02 00 	movl   $0x28e,0x4(%esp)
c0104411:	00 
c0104412:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104419:	e8 27 c0 ff ff       	call   c0100445 <__panic>
    // 验证页表项对应的页面是 p1
    assert(pte2page(*ptep) == p1);
c010441e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104421:	8b 00                	mov    (%eax),%eax
c0104423:	89 04 24             	mov    %eax,(%esp)
c0104426:	e8 08 f1 ff ff       	call   c0103533 <pte2page>
c010442b:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010442e:	74 24                	je     c0104454 <check_pgdir+0x195>
c0104430:	c7 44 24 0c 51 9b 10 	movl   $0xc0109b51,0xc(%esp)
c0104437:	c0 
c0104438:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c010443f:	c0 
c0104440:	c7 44 24 04 90 02 00 	movl   $0x290,0x4(%esp)
c0104447:	00 
c0104448:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c010444f:	e8 f1 bf ff ff       	call   c0100445 <__panic>
    // 验证 p1 的引用计数为 1
    assert(page_ref(p1) == 1);
c0104454:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104457:	89 04 24             	mov    %eax,(%esp)
c010445a:	e8 2a f1 ff ff       	call   c0103589 <page_ref>
c010445f:	83 f8 01             	cmp    $0x1,%eax
c0104462:	74 24                	je     c0104488 <check_pgdir+0x1c9>
c0104464:	c7 44 24 0c 67 9b 10 	movl   $0xc0109b67,0xc(%esp)
c010446b:	c0 
c010446c:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104473:	c0 
c0104474:	c7 44 24 04 92 02 00 	movl   $0x292,0x4(%esp)
c010447b:	00 
c010447c:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104483:	e8 bd bf ff ff       	call   c0100445 <__panic>
    // 获取虚拟地址 PGSIZE 对应的页表项指针
    ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1];
c0104488:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c010448d:	8b 00                	mov    (%eax),%eax
c010448f:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0104494:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0104497:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010449a:	c1 e8 0c             	shr    $0xc,%eax
c010449d:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01044a0:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c01044a5:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c01044a8:	72 23                	jb     c01044cd <check_pgdir+0x20e>
c01044aa:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01044ad:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01044b1:	c7 44 24 08 20 99 10 	movl   $0xc0109920,0x8(%esp)
c01044b8:	c0 
c01044b9:	c7 44 24 04 94 02 00 	movl   $0x294,0x4(%esp)
c01044c0:	00 
c01044c1:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01044c8:	e8 78 bf ff ff       	call   c0100445 <__panic>
c01044cd:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01044d0:	2d 00 00 00 40       	sub    $0x40000000,%eax
c01044d5:	83 c0 04             	add    $0x4,%eax
c01044d8:	89 45 f0             	mov    %eax,-0x10(%ebp)
    assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep);
c01044db:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c01044e0:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01044e7:	00 
c01044e8:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c01044ef:	00 
c01044f0:	89 04 24             	mov    %eax,(%esp)
c01044f3:	e8 72 f9 ff ff       	call   c0103e6a <get_pte>
c01044f8:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01044fb:	74 24                	je     c0104521 <check_pgdir+0x262>
c01044fd:	c7 44 24 0c 7c 9b 10 	movl   $0xc0109b7c,0xc(%esp)
c0104504:	c0 
c0104505:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c010450c:	c0 
c010450d:	c7 44 24 04 95 02 00 	movl   $0x295,0x4(%esp)
c0104514:	00 
c0104515:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c010451c:	e8 24 bf ff ff       	call   c0100445 <__panic>
    // 分配一个页面 p2
    p2 = alloc_page();
c0104521:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0104528:	e8 72 f2 ff ff       	call   c010379f <alloc_pages>
c010452d:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    // 将 p2 插入到虚拟地址 PGSIZE，并设置用户和写权限
    assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0);
c0104530:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104535:	c7 44 24 0c 06 00 00 	movl   $0x6,0xc(%esp)
c010453c:	00 
c010453d:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0104544:	00 
c0104545:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0104548:	89 54 24 04          	mov    %edx,0x4(%esp)
c010454c:	89 04 24             	mov    %eax,(%esp)
c010454f:	e8 5b fb ff ff       	call   c01040af <page_insert>
c0104554:	85 c0                	test   %eax,%eax
c0104556:	74 24                	je     c010457c <check_pgdir+0x2bd>
c0104558:	c7 44 24 0c a4 9b 10 	movl   $0xc0109ba4,0xc(%esp)
c010455f:	c0 
c0104560:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104567:	c0 
c0104568:	c7 44 24 04 99 02 00 	movl   $0x299,0x4(%esp)
c010456f:	00 
c0104570:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104577:	e8 c9 be ff ff       	call   c0100445 <__panic>
    // 获取虚拟地址 PGSIZE 对应的页表项指针
    assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL);
c010457c:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104581:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0104588:	00 
c0104589:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0104590:	00 
c0104591:	89 04 24             	mov    %eax,(%esp)
c0104594:	e8 d1 f8 ff ff       	call   c0103e6a <get_pte>
c0104599:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010459c:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01045a0:	75 24                	jne    c01045c6 <check_pgdir+0x307>
c01045a2:	c7 44 24 0c dc 9b 10 	movl   $0xc0109bdc,0xc(%esp)
c01045a9:	c0 
c01045aa:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01045b1:	c0 
c01045b2:	c7 44 24 04 9b 02 00 	movl   $0x29b,0x4(%esp)
c01045b9:	00 
c01045ba:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01045c1:	e8 7f be ff ff       	call   c0100445 <__panic>
    // 验证页表项设置了用户权限
    assert(*ptep & PTE_U);
c01045c6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01045c9:	8b 00                	mov    (%eax),%eax
c01045cb:	83 e0 04             	and    $0x4,%eax
c01045ce:	85 c0                	test   %eax,%eax
c01045d0:	75 24                	jne    c01045f6 <check_pgdir+0x337>
c01045d2:	c7 44 24 0c 0c 9c 10 	movl   $0xc0109c0c,0xc(%esp)
c01045d9:	c0 
c01045da:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01045e1:	c0 
c01045e2:	c7 44 24 04 9d 02 00 	movl   $0x29d,0x4(%esp)
c01045e9:	00 
c01045ea:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01045f1:	e8 4f be ff ff       	call   c0100445 <__panic>
    // 验证页表项设置了写权限
    assert(*ptep & PTE_W);
c01045f6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01045f9:	8b 00                	mov    (%eax),%eax
c01045fb:	83 e0 02             	and    $0x2,%eax
c01045fe:	85 c0                	test   %eax,%eax
c0104600:	75 24                	jne    c0104626 <check_pgdir+0x367>
c0104602:	c7 44 24 0c 1a 9c 10 	movl   $0xc0109c1a,0xc(%esp)
c0104609:	c0 
c010460a:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104611:	c0 
c0104612:	c7 44 24 04 9f 02 00 	movl   $0x29f,0x4(%esp)
c0104619:	00 
c010461a:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104621:	e8 1f be ff ff       	call   c0100445 <__panic>
    // 验证页目录项设置了用户权限
    assert(boot_pgdir[0] & PTE_U);
c0104626:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c010462b:	8b 00                	mov    (%eax),%eax
c010462d:	83 e0 04             	and    $0x4,%eax
c0104630:	85 c0                	test   %eax,%eax
c0104632:	75 24                	jne    c0104658 <check_pgdir+0x399>
c0104634:	c7 44 24 0c 28 9c 10 	movl   $0xc0109c28,0xc(%esp)
c010463b:	c0 
c010463c:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104643:	c0 
c0104644:	c7 44 24 04 a1 02 00 	movl   $0x2a1,0x4(%esp)
c010464b:	00 
c010464c:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104653:	e8 ed bd ff ff       	call   c0100445 <__panic>
    // 验证 p2 的引用计数为 1
    assert(page_ref(p2) == 1);
c0104658:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010465b:	89 04 24             	mov    %eax,(%esp)
c010465e:	e8 26 ef ff ff       	call   c0103589 <page_ref>
c0104663:	83 f8 01             	cmp    $0x1,%eax
c0104666:	74 24                	je     c010468c <check_pgdir+0x3cd>
c0104668:	c7 44 24 0c 3e 9c 10 	movl   $0xc0109c3e,0xc(%esp)
c010466f:	c0 
c0104670:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104677:	c0 
c0104678:	c7 44 24 04 a3 02 00 	movl   $0x2a3,0x4(%esp)
c010467f:	00 
c0104680:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104687:	e8 b9 bd ff ff       	call   c0100445 <__panic>

    // 将 p1 插入到虚拟地址 PGSIZE，替换掉 p2
    assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0);
c010468c:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104691:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0104698:	00 
c0104699:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c01046a0:	00 
c01046a1:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01046a4:	89 54 24 04          	mov    %edx,0x4(%esp)
c01046a8:	89 04 24             	mov    %eax,(%esp)
c01046ab:	e8 ff f9 ff ff       	call   c01040af <page_insert>
c01046b0:	85 c0                	test   %eax,%eax
c01046b2:	74 24                	je     c01046d8 <check_pgdir+0x419>
c01046b4:	c7 44 24 0c 50 9c 10 	movl   $0xc0109c50,0xc(%esp)
c01046bb:	c0 
c01046bc:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01046c3:	c0 
c01046c4:	c7 44 24 04 a6 02 00 	movl   $0x2a6,0x4(%esp)
c01046cb:	00 
c01046cc:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01046d3:	e8 6d bd ff ff       	call   c0100445 <__panic>
    // 验证 p1 的引用计数增加到 2
    assert(page_ref(p1) == 2);
c01046d8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01046db:	89 04 24             	mov    %eax,(%esp)
c01046de:	e8 a6 ee ff ff       	call   c0103589 <page_ref>
c01046e3:	83 f8 02             	cmp    $0x2,%eax
c01046e6:	74 24                	je     c010470c <check_pgdir+0x44d>
c01046e8:	c7 44 24 0c 7c 9c 10 	movl   $0xc0109c7c,0xc(%esp)
c01046ef:	c0 
c01046f0:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01046f7:	c0 
c01046f8:	c7 44 24 04 a8 02 00 	movl   $0x2a8,0x4(%esp)
c01046ff:	00 
c0104700:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104707:	e8 39 bd ff ff       	call   c0100445 <__panic>
    // 验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c010470c:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010470f:	89 04 24             	mov    %eax,(%esp)
c0104712:	e8 72 ee ff ff       	call   c0103589 <page_ref>
c0104717:	85 c0                	test   %eax,%eax
c0104719:	74 24                	je     c010473f <check_pgdir+0x480>
c010471b:	c7 44 24 0c 8e 9c 10 	movl   $0xc0109c8e,0xc(%esp)
c0104722:	c0 
c0104723:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c010472a:	c0 
c010472b:	c7 44 24 04 aa 02 00 	movl   $0x2aa,0x4(%esp)
c0104732:	00 
c0104733:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c010473a:	e8 06 bd ff ff       	call   c0100445 <__panic>
     // 获取虚拟地址 PGSIZE 对应的页表项指针
    assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL);
c010473f:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104744:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c010474b:	00 
c010474c:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0104753:	00 
c0104754:	89 04 24             	mov    %eax,(%esp)
c0104757:	e8 0e f7 ff ff       	call   c0103e6a <get_pte>
c010475c:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010475f:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0104763:	75 24                	jne    c0104789 <check_pgdir+0x4ca>
c0104765:	c7 44 24 0c dc 9b 10 	movl   $0xc0109bdc,0xc(%esp)
c010476c:	c0 
c010476d:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104774:	c0 
c0104775:	c7 44 24 04 ac 02 00 	movl   $0x2ac,0x4(%esp)
c010477c:	00 
c010477d:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104784:	e8 bc bc ff ff       	call   c0100445 <__panic>
    // 验证页表项对应的页面是 p1
    assert(pte2page(*ptep) == p1);
c0104789:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010478c:	8b 00                	mov    (%eax),%eax
c010478e:	89 04 24             	mov    %eax,(%esp)
c0104791:	e8 9d ed ff ff       	call   c0103533 <pte2page>
c0104796:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0104799:	74 24                	je     c01047bf <check_pgdir+0x500>
c010479b:	c7 44 24 0c 51 9b 10 	movl   $0xc0109b51,0xc(%esp)
c01047a2:	c0 
c01047a3:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01047aa:	c0 
c01047ab:	c7 44 24 04 ae 02 00 	movl   $0x2ae,0x4(%esp)
c01047b2:	00 
c01047b3:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01047ba:	e8 86 bc ff ff       	call   c0100445 <__panic>
     // 验证页表项没有设置用户权限
    assert((*ptep & PTE_U) == 0);
c01047bf:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01047c2:	8b 00                	mov    (%eax),%eax
c01047c4:	83 e0 04             	and    $0x4,%eax
c01047c7:	85 c0                	test   %eax,%eax
c01047c9:	74 24                	je     c01047ef <check_pgdir+0x530>
c01047cb:	c7 44 24 0c a0 9c 10 	movl   $0xc0109ca0,0xc(%esp)
c01047d2:	c0 
c01047d3:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01047da:	c0 
c01047db:	c7 44 24 04 b0 02 00 	movl   $0x2b0,0x4(%esp)
c01047e2:	00 
c01047e3:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01047ea:	e8 56 bc ff ff       	call   c0100445 <__panic>
    
    //移除虚拟地址 0x0 的映射，
    page_remove(boot_pgdir, 0x0);
c01047ef:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c01047f4:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01047fb:	00 
c01047fc:	89 04 24             	mov    %eax,(%esp)
c01047ff:	e8 62 f8 ff ff       	call   c0104066 <page_remove>
    //验证 p1 的引用计数减少到 1。
    assert(page_ref(p1) == 1);
c0104804:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104807:	89 04 24             	mov    %eax,(%esp)
c010480a:	e8 7a ed ff ff       	call   c0103589 <page_ref>
c010480f:	83 f8 01             	cmp    $0x1,%eax
c0104812:	74 24                	je     c0104838 <check_pgdir+0x579>
c0104814:	c7 44 24 0c 67 9b 10 	movl   $0xc0109b67,0xc(%esp)
c010481b:	c0 
c010481c:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104823:	c0 
c0104824:	c7 44 24 04 b5 02 00 	movl   $0x2b5,0x4(%esp)
c010482b:	00 
c010482c:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104833:	e8 0d bc ff ff       	call   c0100445 <__panic>
    //验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c0104838:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010483b:	89 04 24             	mov    %eax,(%esp)
c010483e:	e8 46 ed ff ff       	call   c0103589 <page_ref>
c0104843:	85 c0                	test   %eax,%eax
c0104845:	74 24                	je     c010486b <check_pgdir+0x5ac>
c0104847:	c7 44 24 0c 8e 9c 10 	movl   $0xc0109c8e,0xc(%esp)
c010484e:	c0 
c010484f:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104856:	c0 
c0104857:	c7 44 24 04 b7 02 00 	movl   $0x2b7,0x4(%esp)
c010485e:	00 
c010485f:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104866:	e8 da bb ff ff       	call   c0100445 <__panic>

    //移除虚拟地址 PGSIZE 的映射，
    page_remove(boot_pgdir, PGSIZE);
c010486b:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104870:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0104877:	00 
c0104878:	89 04 24             	mov    %eax,(%esp)
c010487b:	e8 e6 f7 ff ff       	call   c0104066 <page_remove>
    //验证 p1 的引用计数减少到 0
    assert(page_ref(p1) == 0);
c0104880:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104883:	89 04 24             	mov    %eax,(%esp)
c0104886:	e8 fe ec ff ff       	call   c0103589 <page_ref>
c010488b:	85 c0                	test   %eax,%eax
c010488d:	74 24                	je     c01048b3 <check_pgdir+0x5f4>
c010488f:	c7 44 24 0c b5 9c 10 	movl   $0xc0109cb5,0xc(%esp)
c0104896:	c0 
c0104897:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c010489e:	c0 
c010489f:	c7 44 24 04 bc 02 00 	movl   $0x2bc,0x4(%esp)
c01048a6:	00 
c01048a7:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01048ae:	e8 92 bb ff ff       	call   c0100445 <__panic>
    //验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c01048b3:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01048b6:	89 04 24             	mov    %eax,(%esp)
c01048b9:	e8 cb ec ff ff       	call   c0103589 <page_ref>
c01048be:	85 c0                	test   %eax,%eax
c01048c0:	74 24                	je     c01048e6 <check_pgdir+0x627>
c01048c2:	c7 44 24 0c 8e 9c 10 	movl   $0xc0109c8e,0xc(%esp)
c01048c9:	c0 
c01048ca:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01048d1:	c0 
c01048d2:	c7 44 24 04 be 02 00 	movl   $0x2be,0x4(%esp)
c01048d9:	00 
c01048da:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01048e1:	e8 5f bb ff ff       	call   c0100445 <__panic>
    
    //验证页目录的第一页表的引用计数为 1。
    assert(page_ref(pde2page(boot_pgdir[0])) == 1);
c01048e6:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c01048eb:	8b 00                	mov    (%eax),%eax
c01048ed:	89 04 24             	mov    %eax,(%esp)
c01048f0:	e8 7c ec ff ff       	call   c0103571 <pde2page>
c01048f5:	89 04 24             	mov    %eax,(%esp)
c01048f8:	e8 8c ec ff ff       	call   c0103589 <page_ref>
c01048fd:	83 f8 01             	cmp    $0x1,%eax
c0104900:	74 24                	je     c0104926 <check_pgdir+0x667>
c0104902:	c7 44 24 0c c8 9c 10 	movl   $0xc0109cc8,0xc(%esp)
c0104909:	c0 
c010490a:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104911:	c0 
c0104912:	c7 44 24 04 c1 02 00 	movl   $0x2c1,0x4(%esp)
c0104919:	00 
c010491a:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104921:	e8 1f bb ff ff       	call   c0100445 <__panic>
    //释放页目录的第一页表
    free_page(pde2page(boot_pgdir[0]));
c0104926:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c010492b:	8b 00                	mov    (%eax),%eax
c010492d:	89 04 24             	mov    %eax,(%esp)
c0104930:	e8 3c ec ff ff       	call   c0103571 <pde2page>
c0104935:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010493c:	00 
c010493d:	89 04 24             	mov    %eax,(%esp)
c0104940:	e8 c9 ee ff ff       	call   c010380e <free_pages>
    //清空页目录的第一页表
    boot_pgdir[0] = 0;
c0104945:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c010494a:	c7 00 00 00 00 00    	movl   $0x0,(%eax)

    cprintf("check_pgdir() succeeded!\n");
c0104950:	c7 04 24 ef 9c 10 c0 	movl   $0xc0109cef,(%esp)
c0104957:	e8 7d b9 ff ff       	call   c01002d9 <cprintf>
}
c010495c:	90                   	nop
c010495d:	c9                   	leave  
c010495e:	c3                   	ret    

c010495f <check_boot_pgdir>:

//检查内核页表 boot_pgdir 的正确性
static void
check_boot_pgdir(void) {
c010495f:	f3 0f 1e fb          	endbr32 
c0104963:	55                   	push   %ebp
c0104964:	89 e5                	mov    %esp,%ebp
c0104966:	83 ec 38             	sub    $0x38,%esp
    pte_t *ptep;// 定义一个指向页表项的指针
    int i;
    for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面
c0104969:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0104970:	e9 ca 00 00 00       	jmp    c0104a3f <check_boot_pgdir+0xe0>
        // 获取第 i 个页面的页表项，并确保其不为空
        assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL);
c0104975:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104978:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c010497b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010497e:	c1 e8 0c             	shr    $0xc,%eax
c0104981:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0104984:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c0104989:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c010498c:	72 23                	jb     c01049b1 <check_boot_pgdir+0x52>
c010498e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0104991:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0104995:	c7 44 24 08 20 99 10 	movl   $0xc0109920,0x8(%esp)
c010499c:	c0 
c010499d:	c7 44 24 04 d1 02 00 	movl   $0x2d1,0x4(%esp)
c01049a4:	00 
c01049a5:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01049ac:	e8 94 ba ff ff       	call   c0100445 <__panic>
c01049b1:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01049b4:	2d 00 00 00 40       	sub    $0x40000000,%eax
c01049b9:	89 c2                	mov    %eax,%edx
c01049bb:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c01049c0:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01049c7:	00 
c01049c8:	89 54 24 04          	mov    %edx,0x4(%esp)
c01049cc:	89 04 24             	mov    %eax,(%esp)
c01049cf:	e8 96 f4 ff ff       	call   c0103e6a <get_pte>
c01049d4:	89 45 dc             	mov    %eax,-0x24(%ebp)
c01049d7:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c01049db:	75 24                	jne    c0104a01 <check_boot_pgdir+0xa2>
c01049dd:	c7 44 24 0c 0c 9d 10 	movl   $0xc0109d0c,0xc(%esp)
c01049e4:	c0 
c01049e5:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c01049ec:	c0 
c01049ed:	c7 44 24 04 d1 02 00 	movl   $0x2d1,0x4(%esp)
c01049f4:	00 
c01049f5:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c01049fc:	e8 44 ba ff ff       	call   c0100445 <__panic>
        // 验证页表项的物理地址是否正确
        assert(PTE_ADDR(*ptep) == i);
c0104a01:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0104a04:	8b 00                	mov    (%eax),%eax
c0104a06:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0104a0b:	89 c2                	mov    %eax,%edx
c0104a0d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104a10:	39 c2                	cmp    %eax,%edx
c0104a12:	74 24                	je     c0104a38 <check_boot_pgdir+0xd9>
c0104a14:	c7 44 24 0c 49 9d 10 	movl   $0xc0109d49,0xc(%esp)
c0104a1b:	c0 
c0104a1c:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104a23:	c0 
c0104a24:	c7 44 24 04 d3 02 00 	movl   $0x2d3,0x4(%esp)
c0104a2b:	00 
c0104a2c:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104a33:	e8 0d ba ff ff       	call   c0100445 <__panic>
    for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面
c0104a38:	81 45 f4 00 10 00 00 	addl   $0x1000,-0xc(%ebp)
c0104a3f:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0104a42:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c0104a47:	39 c2                	cmp    %eax,%edx
c0104a49:	0f 82 26 ff ff ff    	jb     c0104975 <check_boot_pgdir+0x16>
    }
    // 验证页目录项的物理地址是否正确
    assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir));
c0104a4f:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104a54:	05 ac 0f 00 00       	add    $0xfac,%eax
c0104a59:	8b 00                	mov    (%eax),%eax
c0104a5b:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0104a60:	89 c2                	mov    %eax,%edx
c0104a62:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104a67:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0104a6a:	81 7d f0 ff ff ff bf 	cmpl   $0xbfffffff,-0x10(%ebp)
c0104a71:	77 23                	ja     c0104a96 <check_boot_pgdir+0x137>
c0104a73:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104a76:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0104a7a:	c7 44 24 08 44 99 10 	movl   $0xc0109944,0x8(%esp)
c0104a81:	c0 
c0104a82:	c7 44 24 04 d6 02 00 	movl   $0x2d6,0x4(%esp)
c0104a89:	00 
c0104a8a:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104a91:	e8 af b9 ff ff       	call   c0100445 <__panic>
c0104a96:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104a99:	05 00 00 00 40       	add    $0x40000000,%eax
c0104a9e:	39 d0                	cmp    %edx,%eax
c0104aa0:	74 24                	je     c0104ac6 <check_boot_pgdir+0x167>
c0104aa2:	c7 44 24 0c 60 9d 10 	movl   $0xc0109d60,0xc(%esp)
c0104aa9:	c0 
c0104aaa:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104ab1:	c0 
c0104ab2:	c7 44 24 04 d6 02 00 	movl   $0x2d6,0x4(%esp)
c0104ab9:	00 
c0104aba:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104ac1:	e8 7f b9 ff ff       	call   c0100445 <__panic>

    assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0
c0104ac6:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104acb:	8b 00                	mov    (%eax),%eax
c0104acd:	85 c0                	test   %eax,%eax
c0104acf:	74 24                	je     c0104af5 <check_boot_pgdir+0x196>
c0104ad1:	c7 44 24 0c 94 9d 10 	movl   $0xc0109d94,0xc(%esp)
c0104ad8:	c0 
c0104ad9:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104ae0:	c0 
c0104ae1:	c7 44 24 04 d8 02 00 	movl   $0x2d8,0x4(%esp)
c0104ae8:	00 
c0104ae9:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104af0:	e8 50 b9 ff ff       	call   c0100445 <__panic>

    struct Page *p;// 定义一个指向页面的指针
    p = alloc_page();// 分配一个页面
c0104af5:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0104afc:	e8 9e ec ff ff       	call   c010379f <alloc_pages>
c0104b01:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 将页面插入到虚拟地址 0x100，并确保操作成功
    assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0);
c0104b04:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104b09:	c7 44 24 0c 02 00 00 	movl   $0x2,0xc(%esp)
c0104b10:	00 
c0104b11:	c7 44 24 08 00 01 00 	movl   $0x100,0x8(%esp)
c0104b18:	00 
c0104b19:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0104b1c:	89 54 24 04          	mov    %edx,0x4(%esp)
c0104b20:	89 04 24             	mov    %eax,(%esp)
c0104b23:	e8 87 f5 ff ff       	call   c01040af <page_insert>
c0104b28:	85 c0                	test   %eax,%eax
c0104b2a:	74 24                	je     c0104b50 <check_boot_pgdir+0x1f1>
c0104b2c:	c7 44 24 0c a8 9d 10 	movl   $0xc0109da8,0xc(%esp)
c0104b33:	c0 
c0104b34:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104b3b:	c0 
c0104b3c:	c7 44 24 04 dd 02 00 	movl   $0x2dd,0x4(%esp)
c0104b43:	00 
c0104b44:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104b4b:	e8 f5 b8 ff ff       	call   c0100445 <__panic>
    assert(page_ref(p) == 1);// 验证页面的引用计数为1
c0104b50:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104b53:	89 04 24             	mov    %eax,(%esp)
c0104b56:	e8 2e ea ff ff       	call   c0103589 <page_ref>
c0104b5b:	83 f8 01             	cmp    $0x1,%eax
c0104b5e:	74 24                	je     c0104b84 <check_boot_pgdir+0x225>
c0104b60:	c7 44 24 0c d6 9d 10 	movl   $0xc0109dd6,0xc(%esp)
c0104b67:	c0 
c0104b68:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104b6f:	c0 
c0104b70:	c7 44 24 04 de 02 00 	movl   $0x2de,0x4(%esp)
c0104b77:	00 
c0104b78:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104b7f:	e8 c1 b8 ff ff       	call   c0100445 <__panic>
    // 将页面插入到虚拟地址 0x100 + PGSIZE，并确保操作成功
    assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0);
c0104b84:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104b89:	c7 44 24 0c 02 00 00 	movl   $0x2,0xc(%esp)
c0104b90:	00 
c0104b91:	c7 44 24 08 00 11 00 	movl   $0x1100,0x8(%esp)
c0104b98:	00 
c0104b99:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0104b9c:	89 54 24 04          	mov    %edx,0x4(%esp)
c0104ba0:	89 04 24             	mov    %eax,(%esp)
c0104ba3:	e8 07 f5 ff ff       	call   c01040af <page_insert>
c0104ba8:	85 c0                	test   %eax,%eax
c0104baa:	74 24                	je     c0104bd0 <check_boot_pgdir+0x271>
c0104bac:	c7 44 24 0c e8 9d 10 	movl   $0xc0109de8,0xc(%esp)
c0104bb3:	c0 
c0104bb4:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104bbb:	c0 
c0104bbc:	c7 44 24 04 e0 02 00 	movl   $0x2e0,0x4(%esp)
c0104bc3:	00 
c0104bc4:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104bcb:	e8 75 b8 ff ff       	call   c0100445 <__panic>
    assert(page_ref(p) == 2);// 验证页面的引用计数为2
c0104bd0:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104bd3:	89 04 24             	mov    %eax,(%esp)
c0104bd6:	e8 ae e9 ff ff       	call   c0103589 <page_ref>
c0104bdb:	83 f8 02             	cmp    $0x2,%eax
c0104bde:	74 24                	je     c0104c04 <check_boot_pgdir+0x2a5>
c0104be0:	c7 44 24 0c 1f 9e 10 	movl   $0xc0109e1f,0xc(%esp)
c0104be7:	c0 
c0104be8:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104bef:	c0 
c0104bf0:	c7 44 24 04 e1 02 00 	movl   $0x2e1,0x4(%esp)
c0104bf7:	00 
c0104bf8:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104bff:	e8 41 b8 ff ff       	call   c0100445 <__panic>

    const char *str = "ucore: Hello world!!";// 定义一个字符串
c0104c04:	c7 45 e8 30 9e 10 c0 	movl   $0xc0109e30,-0x18(%ebp)
    strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100
c0104c0b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104c0e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104c12:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c0104c19:	e8 eb 37 00 00       	call   c0108409 <strcpy>
    // 验证两个映射地址的数据是否一致
    assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0);
c0104c1e:	c7 44 24 04 00 11 00 	movl   $0x1100,0x4(%esp)
c0104c25:	00 
c0104c26:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c0104c2d:	e8 55 38 00 00       	call   c0108487 <strcmp>
c0104c32:	85 c0                	test   %eax,%eax
c0104c34:	74 24                	je     c0104c5a <check_boot_pgdir+0x2fb>
c0104c36:	c7 44 24 0c 48 9e 10 	movl   $0xc0109e48,0xc(%esp)
c0104c3d:	c0 
c0104c3e:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104c45:	c0 
c0104c46:	c7 44 24 04 e6 02 00 	movl   $0x2e6,0x4(%esp)
c0104c4d:	00 
c0104c4e:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104c55:	e8 eb b7 ff ff       	call   c0100445 <__panic>
    // 在页面的 0x100 偏移处设置字符串结束符
    *(char *)(page2kva(p) + 0x100) = '\0';
c0104c5a:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104c5d:	89 04 24             	mov    %eax,(%esp)
c0104c60:	e8 30 e8 ff ff       	call   c0103495 <page2kva>
c0104c65:	05 00 01 00 00       	add    $0x100,%eax
c0104c6a:	c6 00 00             	movb   $0x0,(%eax)
    assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0
c0104c6d:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c0104c74:	e8 32 37 00 00       	call   c01083ab <strlen>
c0104c79:	85 c0                	test   %eax,%eax
c0104c7b:	74 24                	je     c0104ca1 <check_boot_pgdir+0x342>
c0104c7d:	c7 44 24 0c 80 9e 10 	movl   $0xc0109e80,0xc(%esp)
c0104c84:	c0 
c0104c85:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104c8c:	c0 
c0104c8d:	c7 44 24 04 e9 02 00 	movl   $0x2e9,0x4(%esp)
c0104c94:	00 
c0104c95:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104c9c:	e8 a4 b7 ff ff       	call   c0100445 <__panic>

    free_page(p);// 释放页面 p
c0104ca1:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0104ca8:	00 
c0104ca9:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104cac:	89 04 24             	mov    %eax,(%esp)
c0104caf:	e8 5a eb ff ff       	call   c010380e <free_pages>
    free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面
c0104cb4:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104cb9:	8b 00                	mov    (%eax),%eax
c0104cbb:	89 04 24             	mov    %eax,(%esp)
c0104cbe:	e8 ae e8 ff ff       	call   c0103571 <pde2page>
c0104cc3:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0104cca:	00 
c0104ccb:	89 04 24             	mov    %eax,(%esp)
c0104cce:	e8 3b eb ff ff       	call   c010380e <free_pages>
    boot_pgdir[0] = 0;// 将页目录的第一个项设为0
c0104cd3:	a1 e0 39 12 c0       	mov    0xc01239e0,%eax
c0104cd8:	c7 00 00 00 00 00    	movl   $0x0,(%eax)

    cprintf("check_boot_pgdir() succeeded!\n");// 输出成功信息
c0104cde:	c7 04 24 a4 9e 10 c0 	movl   $0xc0109ea4,(%esp)
c0104ce5:	e8 ef b5 ff ff       	call   c01002d9 <cprintf>
}
c0104cea:	90                   	nop
c0104ceb:	c9                   	leave  
c0104cec:	c3                   	ret    

c0104ced <perm2str>:

//perm2str - use string 'u,r,w,-' to present the permission
static const char *
perm2str(int perm) {
c0104ced:	f3 0f 1e fb          	endbr32 
c0104cf1:	55                   	push   %ebp
c0104cf2:	89 e5                	mov    %esp,%ebp
    //定义一个静态字符数组 str，长度为4
    static char str[4];
    //如果 perm 与 PTE_U 按位与的结果不为0，则 str[0] 设置为 'u'，否则设置为 '-'
    str[0] = (perm & PTE_U) ? 'u' : '-';
c0104cf4:	8b 45 08             	mov    0x8(%ebp),%eax
c0104cf7:	83 e0 04             	and    $0x4,%eax
c0104cfa:	85 c0                	test   %eax,%eax
c0104cfc:	74 04                	je     c0104d02 <perm2str+0x15>
c0104cfe:	b0 75                	mov    $0x75,%al
c0104d00:	eb 02                	jmp    c0104d04 <perm2str+0x17>
c0104d02:	b0 2d                	mov    $0x2d,%al
c0104d04:	a2 08 70 12 c0       	mov    %al,0xc0127008
    //str[1] 始终设置为 'r'
    str[1] = 'r';
c0104d09:	c6 05 09 70 12 c0 72 	movb   $0x72,0xc0127009
    //如果 perm 与 PTE_W 按位与的结果不为0，则 str[2] 设置为 'w'，否则设置为 '-'
    str[2] = (perm & PTE_W) ? 'w' : '-';
c0104d10:	8b 45 08             	mov    0x8(%ebp),%eax
c0104d13:	83 e0 02             	and    $0x2,%eax
c0104d16:	85 c0                	test   %eax,%eax
c0104d18:	74 04                	je     c0104d1e <perm2str+0x31>
c0104d1a:	b0 77                	mov    $0x77,%al
c0104d1c:	eb 02                	jmp    c0104d20 <perm2str+0x33>
c0104d1e:	b0 2d                	mov    $0x2d,%al
c0104d20:	a2 0a 70 12 c0       	mov    %al,0xc012700a
    //str[3] 设置为字符串结束符 \0
    str[3] = '\0';
c0104d25:	c6 05 0b 70 12 c0 00 	movb   $0x0,0xc012700b
    return str;
c0104d2c:	b8 08 70 12 c0       	mov    $0xc0127008,%eax
}
c0104d31:	5d                   	pop    %ebp
c0104d32:	c3                   	ret    

c0104d33 <get_pgtable_items>:
//  left_store:  the pointer of the high side of table's next range
//  right_store: the pointer of the low side of table's next range
// return value: 0 - not a invalid item range, perm - a valid item range with perm permission 
//从页表中获取指定范围内的有效项，并根据权限进行处理。
static int
get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) {
c0104d33:	f3 0f 1e fb          	endbr32 
c0104d37:	55                   	push   %ebp
c0104d38:	89 e5                	mov    %esp,%ebp
c0104d3a:	83 ec 10             	sub    $0x10,%esp
    if (start >= right) {// 检查起始索引是否超出右边界
c0104d3d:	8b 45 10             	mov    0x10(%ebp),%eax
c0104d40:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0104d43:	72 0d                	jb     c0104d52 <get_pgtable_items+0x1f>
        return 0;// 如果超出右边界，返回0
c0104d45:	b8 00 00 00 00       	mov    $0x0,%eax
c0104d4a:	e9 98 00 00 00       	jmp    c0104de7 <get_pgtable_items+0xb4>
    }
    while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项（PTE_P位为1的项）
        start ++;// 索引递增
c0104d4f:	ff 45 10             	incl   0x10(%ebp)
    while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项（PTE_P位为1的项）
c0104d52:	8b 45 10             	mov    0x10(%ebp),%eax
c0104d55:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0104d58:	73 18                	jae    c0104d72 <get_pgtable_items+0x3f>
c0104d5a:	8b 45 10             	mov    0x10(%ebp),%eax
c0104d5d:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0104d64:	8b 45 14             	mov    0x14(%ebp),%eax
c0104d67:	01 d0                	add    %edx,%eax
c0104d69:	8b 00                	mov    (%eax),%eax
c0104d6b:	83 e0 01             	and    $0x1,%eax
c0104d6e:	85 c0                	test   %eax,%eax
c0104d70:	74 dd                	je     c0104d4f <get_pgtable_items+0x1c>
    }
    if (start < right) {// 检查是否找到有效项
c0104d72:	8b 45 10             	mov    0x10(%ebp),%eax
c0104d75:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0104d78:	73 68                	jae    c0104de2 <get_pgtable_items+0xaf>
        if (left_store != NULL) {// 如果left_store不为NULL
c0104d7a:	83 7d 18 00          	cmpl   $0x0,0x18(%ebp)
c0104d7e:	74 08                	je     c0104d88 <get_pgtable_items+0x55>
            *left_store = start;// 记录左边界索引
c0104d80:	8b 45 18             	mov    0x18(%ebp),%eax
c0104d83:	8b 55 10             	mov    0x10(%ebp),%edx
c0104d86:	89 10                	mov    %edx,(%eax)
        }
        int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引
c0104d88:	8b 45 10             	mov    0x10(%ebp),%eax
c0104d8b:	8d 50 01             	lea    0x1(%eax),%edx
c0104d8e:	89 55 10             	mov    %edx,0x10(%ebp)
c0104d91:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0104d98:	8b 45 14             	mov    0x14(%ebp),%eax
c0104d9b:	01 d0                	add    %edx,%eax
c0104d9d:	8b 00                	mov    (%eax),%eax
c0104d9f:	83 e0 07             	and    $0x7,%eax
c0104da2:	89 45 fc             	mov    %eax,-0x4(%ebp)
        while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项
c0104da5:	eb 03                	jmp    c0104daa <get_pgtable_items+0x77>
            start ++;// 索引递增
c0104da7:	ff 45 10             	incl   0x10(%ebp)
        while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项
c0104daa:	8b 45 10             	mov    0x10(%ebp),%eax
c0104dad:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0104db0:	73 1d                	jae    c0104dcf <get_pgtable_items+0x9c>
c0104db2:	8b 45 10             	mov    0x10(%ebp),%eax
c0104db5:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0104dbc:	8b 45 14             	mov    0x14(%ebp),%eax
c0104dbf:	01 d0                	add    %edx,%eax
c0104dc1:	8b 00                	mov    (%eax),%eax
c0104dc3:	83 e0 07             	and    $0x7,%eax
c0104dc6:	89 c2                	mov    %eax,%edx
c0104dc8:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0104dcb:	39 c2                	cmp    %eax,%edx
c0104dcd:	74 d8                	je     c0104da7 <get_pgtable_items+0x74>
        }
        if (right_store != NULL) {// 如果right_store不为NULL
c0104dcf:	83 7d 1c 00          	cmpl   $0x0,0x1c(%ebp)
c0104dd3:	74 08                	je     c0104ddd <get_pgtable_items+0xaa>
            *right_store = start;// 记录右边界索引
c0104dd5:	8b 45 1c             	mov    0x1c(%ebp),%eax
c0104dd8:	8b 55 10             	mov    0x10(%ebp),%edx
c0104ddb:	89 10                	mov    %edx,(%eax)
        }
        return perm;// 返回用户权限位
c0104ddd:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0104de0:	eb 05                	jmp    c0104de7 <get_pgtable_items+0xb4>
    }
    return 0;// 如果未找到有效项，返回0
c0104de2:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104de7:	c9                   	leave  
c0104de8:	c3                   	ret    

c0104de9 <print_pgdir>:

//print_pgdir - print the PDT&PT
void
print_pgdir(void) {
c0104de9:	f3 0f 1e fb          	endbr32 
c0104ded:	55                   	push   %ebp
c0104dee:	89 e5                	mov    %esp,%ebp
c0104df0:	57                   	push   %edi
c0104df1:	56                   	push   %esi
c0104df2:	53                   	push   %ebx
c0104df3:	83 ec 4c             	sub    $0x4c,%esp
    cprintf("-------------------- BEGIN --------------------\n");
c0104df6:	c7 04 24 c4 9e 10 c0 	movl   $0xc0109ec4,(%esp)
c0104dfd:	e8 d7 b4 ff ff       	call   c01002d9 <cprintf>
    // 定义变量 left, right 和 perm
    size_t left, right = 0, perm;
c0104e02:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
    // 遍历页目录项
    while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) {
c0104e09:	e9 fa 00 00 00       	jmp    c0104f08 <print_pgdir+0x11f>
        // 打印页目录项的信息
        cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left,
c0104e0e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0104e11:	89 04 24             	mov    %eax,(%esp)
c0104e14:	e8 d4 fe ff ff       	call   c0104ced <perm2str>
                left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm));
c0104e19:	8b 4d dc             	mov    -0x24(%ebp),%ecx
c0104e1c:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0104e1f:	29 d1                	sub    %edx,%ecx
c0104e21:	89 ca                	mov    %ecx,%edx
        cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left,
c0104e23:	89 d6                	mov    %edx,%esi
c0104e25:	c1 e6 16             	shl    $0x16,%esi
c0104e28:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0104e2b:	89 d3                	mov    %edx,%ebx
c0104e2d:	c1 e3 16             	shl    $0x16,%ebx
c0104e30:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0104e33:	89 d1                	mov    %edx,%ecx
c0104e35:	c1 e1 16             	shl    $0x16,%ecx
c0104e38:	8b 7d dc             	mov    -0x24(%ebp),%edi
c0104e3b:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0104e3e:	29 d7                	sub    %edx,%edi
c0104e40:	89 fa                	mov    %edi,%edx
c0104e42:	89 44 24 14          	mov    %eax,0x14(%esp)
c0104e46:	89 74 24 10          	mov    %esi,0x10(%esp)
c0104e4a:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c0104e4e:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0104e52:	89 54 24 04          	mov    %edx,0x4(%esp)
c0104e56:	c7 04 24 f5 9e 10 c0 	movl   $0xc0109ef5,(%esp)
c0104e5d:	e8 77 b4 ff ff       	call   c01002d9 <cprintf>
        // 计算页表项的起始和结束索引
        size_t l, r = left * NPTEENTRY;
c0104e62:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0104e65:	c1 e0 0a             	shl    $0xa,%eax
c0104e68:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        // 遍历页表项
        while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) {
c0104e6b:	eb 54                	jmp    c0104ec1 <print_pgdir+0xd8>
            // 打印页表项的信息
            cprintf("  |-- PTE(%05x) %08x-%08x %08x %s\n", r - l,
c0104e6d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0104e70:	89 04 24             	mov    %eax,(%esp)
c0104e73:	e8 75 fe ff ff       	call   c0104ced <perm2str>
                    l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm));
c0104e78:	8b 4d d4             	mov    -0x2c(%ebp),%ecx
c0104e7b:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0104e7e:	29 d1                	sub    %edx,%ecx
c0104e80:	89 ca                	mov    %ecx,%edx
            cprintf("  |-- PTE(%05x) %08x-%08x %08x %s\n", r - l,
c0104e82:	89 d6                	mov    %edx,%esi
c0104e84:	c1 e6 0c             	shl    $0xc,%esi
c0104e87:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0104e8a:	89 d3                	mov    %edx,%ebx
c0104e8c:	c1 e3 0c             	shl    $0xc,%ebx
c0104e8f:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0104e92:	89 d1                	mov    %edx,%ecx
c0104e94:	c1 e1 0c             	shl    $0xc,%ecx
c0104e97:	8b 7d d4             	mov    -0x2c(%ebp),%edi
c0104e9a:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0104e9d:	29 d7                	sub    %edx,%edi
c0104e9f:	89 fa                	mov    %edi,%edx
c0104ea1:	89 44 24 14          	mov    %eax,0x14(%esp)
c0104ea5:	89 74 24 10          	mov    %esi,0x10(%esp)
c0104ea9:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c0104ead:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0104eb1:	89 54 24 04          	mov    %edx,0x4(%esp)
c0104eb5:	c7 04 24 14 9f 10 c0 	movl   $0xc0109f14,(%esp)
c0104ebc:	e8 18 b4 ff ff       	call   c01002d9 <cprintf>
        while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) {
c0104ec1:	be 00 00 c0 fa       	mov    $0xfac00000,%esi
c0104ec6:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0104ec9:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0104ecc:	89 d3                	mov    %edx,%ebx
c0104ece:	c1 e3 0a             	shl    $0xa,%ebx
c0104ed1:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0104ed4:	89 d1                	mov    %edx,%ecx
c0104ed6:	c1 e1 0a             	shl    $0xa,%ecx
c0104ed9:	8d 55 d4             	lea    -0x2c(%ebp),%edx
c0104edc:	89 54 24 14          	mov    %edx,0x14(%esp)
c0104ee0:	8d 55 d8             	lea    -0x28(%ebp),%edx
c0104ee3:	89 54 24 10          	mov    %edx,0x10(%esp)
c0104ee7:	89 74 24 0c          	mov    %esi,0xc(%esp)
c0104eeb:	89 44 24 08          	mov    %eax,0x8(%esp)
c0104eef:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c0104ef3:	89 0c 24             	mov    %ecx,(%esp)
c0104ef6:	e8 38 fe ff ff       	call   c0104d33 <get_pgtable_items>
c0104efb:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0104efe:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0104f02:	0f 85 65 ff ff ff    	jne    c0104e6d <print_pgdir+0x84>
    while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) {
c0104f08:	b9 00 b0 fe fa       	mov    $0xfafeb000,%ecx
c0104f0d:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0104f10:	8d 55 dc             	lea    -0x24(%ebp),%edx
c0104f13:	89 54 24 14          	mov    %edx,0x14(%esp)
c0104f17:	8d 55 e0             	lea    -0x20(%ebp),%edx
c0104f1a:	89 54 24 10          	mov    %edx,0x10(%esp)
c0104f1e:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c0104f22:	89 44 24 08          	mov    %eax,0x8(%esp)
c0104f26:	c7 44 24 04 00 04 00 	movl   $0x400,0x4(%esp)
c0104f2d:	00 
c0104f2e:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0104f35:	e8 f9 fd ff ff       	call   c0104d33 <get_pgtable_items>
c0104f3a:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0104f3d:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0104f41:	0f 85 c7 fe ff ff    	jne    c0104e0e <print_pgdir+0x25>
        }
    }
    cprintf("--------------------- END ---------------------\n");
c0104f47:	c7 04 24 38 9f 10 c0 	movl   $0xc0109f38,(%esp)
c0104f4e:	e8 86 b3 ff ff       	call   c01002d9 <cprintf>
}
c0104f53:	90                   	nop
c0104f54:	83 c4 4c             	add    $0x4c,%esp
c0104f57:	5b                   	pop    %ebx
c0104f58:	5e                   	pop    %esi
c0104f59:	5f                   	pop    %edi
c0104f5a:	5d                   	pop    %ebp
c0104f5b:	c3                   	ret    

c0104f5c <kmalloc>:

//size_t n，表示请求的内存大小。
void *
kmalloc(size_t n) {
c0104f5c:	f3 0f 1e fb          	endbr32 
c0104f60:	55                   	push   %ebp
c0104f61:	89 e5                	mov    %esp,%ebp
c0104f63:	83 ec 28             	sub    $0x28,%esp
    //ptr用于存储分配的内存地址。
    void * ptr=NULL;
c0104f66:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    //base用于存储分配的页面基址
    struct Page *base=NULL;
c0104f6d:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    assert(n > 0 && n < 1024*0124);
c0104f74:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104f78:	74 09                	je     c0104f83 <kmalloc+0x27>
c0104f7a:	81 7d 08 ff 4f 01 00 	cmpl   $0x14fff,0x8(%ebp)
c0104f81:	76 24                	jbe    c0104fa7 <kmalloc+0x4b>
c0104f83:	c7 44 24 0c 69 9f 10 	movl   $0xc0109f69,0xc(%esp)
c0104f8a:	c0 
c0104f8b:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104f92:	c0 
c0104f93:	c7 44 24 04 44 03 00 	movl   $0x344,0x4(%esp)
c0104f9a:	00 
c0104f9b:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104fa2:	e8 9e b4 ff ff       	call   c0100445 <__panic>
    //计算所需页数
    int num_pages=(n+PGSIZE-1)/PGSIZE;
c0104fa7:	8b 45 08             	mov    0x8(%ebp),%eax
c0104faa:	05 ff 0f 00 00       	add    $0xfff,%eax
c0104faf:	c1 e8 0c             	shr    $0xc,%eax
c0104fb2:	89 45 ec             	mov    %eax,-0x14(%ebp)
    //分配num_pages个页面，结果存储在 base 中
    base = alloc_pages(num_pages);
c0104fb5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104fb8:	89 04 24             	mov    %eax,(%esp)
c0104fbb:	e8 df e7 ff ff       	call   c010379f <alloc_pages>
c0104fc0:	89 45 f0             	mov    %eax,-0x10(%ebp)
    //检查页面分配是否成功
    assert(base != NULL);
c0104fc3:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0104fc7:	75 24                	jne    c0104fed <kmalloc+0x91>
c0104fc9:	c7 44 24 0c 80 9f 10 	movl   $0xc0109f80,0xc(%esp)
c0104fd0:	c0 
c0104fd1:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0104fd8:	c0 
c0104fd9:	c7 44 24 04 4a 03 00 	movl   $0x34a,0x4(%esp)
c0104fe0:	00 
c0104fe1:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0104fe8:	e8 58 b4 ff ff       	call   c0100445 <__panic>
    //将分配的页面基址 base 转换为内核虚拟地址，结果存储在 ptr 中
    ptr=page2kva(base);
c0104fed:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104ff0:	89 04 24             	mov    %eax,(%esp)
c0104ff3:	e8 9d e4 ff ff       	call   c0103495 <page2kva>
c0104ff8:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return ptr;
c0104ffb:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0104ffe:	c9                   	leave  
c0104fff:	c3                   	ret    

c0105000 <kfree>:

void 
kfree(void *ptr, size_t n) {
c0105000:	f3 0f 1e fb          	endbr32 
c0105004:	55                   	push   %ebp
c0105005:	89 e5                	mov    %esp,%ebp
c0105007:	83 ec 28             	sub    $0x28,%esp
    assert(n > 0 && n < 1024*0124);
c010500a:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010500e:	74 09                	je     c0105019 <kfree+0x19>
c0105010:	81 7d 0c ff 4f 01 00 	cmpl   $0x14fff,0xc(%ebp)
c0105017:	76 24                	jbe    c010503d <kfree+0x3d>
c0105019:	c7 44 24 0c 69 9f 10 	movl   $0xc0109f69,0xc(%esp)
c0105020:	c0 
c0105021:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0105028:	c0 
c0105029:	c7 44 24 04 52 03 00 	movl   $0x352,0x4(%esp)
c0105030:	00 
c0105031:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0105038:	e8 08 b4 ff ff       	call   c0100445 <__panic>
    assert(ptr != NULL);
c010503d:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0105041:	75 24                	jne    c0105067 <kfree+0x67>
c0105043:	c7 44 24 0c 8d 9f 10 	movl   $0xc0109f8d,0xc(%esp)
c010504a:	c0 
c010504b:	c7 44 24 08 0d 9a 10 	movl   $0xc0109a0d,0x8(%esp)
c0105052:	c0 
c0105053:	c7 44 24 04 53 03 00 	movl   $0x353,0x4(%esp)
c010505a:	00 
c010505b:	c7 04 24 e8 99 10 c0 	movl   $0xc01099e8,(%esp)
c0105062:	e8 de b3 ff ff       	call   c0100445 <__panic>
    struct Page *base=NULL;
c0105067:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    //计算需要释放的页数
    int num_pages=(n+PGSIZE-1)/PGSIZE;
c010506e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105071:	05 ff 0f 00 00       	add    $0xfff,%eax
c0105076:	c1 e8 0c             	shr    $0xc,%eax
c0105079:	89 45 f0             	mov    %eax,-0x10(%ebp)
    //将虚拟地址 ptr 转换为物理页的指针 base
    base = kva2page(ptr);
c010507c:	8b 45 08             	mov    0x8(%ebp),%eax
c010507f:	89 04 24             	mov    %eax,(%esp)
c0105082:	e8 62 e4 ff ff       	call   c01034e9 <kva2page>
c0105087:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //释放从 base 开始的 num_pages 个页面
    free_pages(base, num_pages);
c010508a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010508d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105091:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105094:	89 04 24             	mov    %eax,(%esp)
c0105097:	e8 72 e7 ff ff       	call   c010380e <free_pages>
}
c010509c:	90                   	nop
c010509d:	c9                   	leave  
c010509e:	c3                   	ret    

c010509f <_fifo_init_mm>:
 * (2) _fifo_init_mm: init pra_list_head and let  mm->sm_priv point to the addr of pra_list_head.
 *              Now, From the memory control struct mm_struct, we can access FIFO PRA
 */
static int
_fifo_init_mm(struct mm_struct *mm)
{     
c010509f:	f3 0f 1e fb          	endbr32 
c01050a3:	55                   	push   %ebp
c01050a4:	89 e5                	mov    %esp,%ebp
c01050a6:	83 ec 10             	sub    $0x10,%esp
c01050a9:	c7 45 fc 7c 70 12 c0 	movl   $0xc012707c,-0x4(%ebp)
 * list_init - initialize a new entry
 * @elm:        new entry to be initialized
 * */
static inline void
list_init(list_entry_t *elm) {
    elm->prev = elm->next = elm;
c01050b0:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01050b3:	8b 55 fc             	mov    -0x4(%ebp),%edx
c01050b6:	89 50 04             	mov    %edx,0x4(%eax)
c01050b9:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01050bc:	8b 50 04             	mov    0x4(%eax),%edx
c01050bf:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01050c2:	89 10                	mov    %edx,(%eax)
}
c01050c4:	90                   	nop
    //初始化一个链表头 pra_list_head
     list_init(&pra_list_head);
     //将 mm 结构中的 sm_priv 字段指向这个链表头
     mm->sm_priv = &pra_list_head;
c01050c5:	8b 45 08             	mov    0x8(%ebp),%eax
c01050c8:	c7 40 14 7c 70 12 c0 	movl   $0xc012707c,0x14(%eax)
     //cprintf(" mm->sm_priv %x in fifo_init_mm\n",mm->sm_priv);
     //返回 0 表示成功
     return 0;
c01050cf:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01050d4:	c9                   	leave  
c01050d5:	c3                   	ret    

c01050d6 <_fifo_map_swappable>:
/*
 * (3)_fifo_map_swappable: According FIFO PRA, we should link the most recent arrival page at the back of pra_list_head qeueue
 */
static int
_fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
{
c01050d6:	f3 0f 1e fb          	endbr32 
c01050da:	55                   	push   %ebp
c01050db:	89 e5                	mov    %esp,%ebp
c01050dd:	83 ec 48             	sub    $0x48,%esp
    //获取 mm_struct 结构中的 sm_priv 指针，
    //并将其转换为 list_entry_t 类型的链表头指针 head
    list_entry_t *head=(list_entry_t*) mm->sm_priv;
c01050e0:	8b 45 08             	mov    0x8(%ebp),%eax
c01050e3:	8b 40 14             	mov    0x14(%eax),%eax
c01050e6:	89 45 f4             	mov    %eax,-0xc(%ebp)
    list_entry_t *entry=&(page->pra_page_link);
c01050e9:	8b 45 10             	mov    0x10(%ebp),%eax
c01050ec:	83 c0 14             	add    $0x14,%eax
c01050ef:	89 45 f0             	mov    %eax,-0x10(%ebp)
 
    assert(entry != NULL && head != NULL);
c01050f2:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01050f6:	74 06                	je     c01050fe <_fifo_map_swappable+0x28>
c01050f8:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01050fc:	75 24                	jne    c0105122 <_fifo_map_swappable+0x4c>
c01050fe:	c7 44 24 0c 9c 9f 10 	movl   $0xc0109f9c,0xc(%esp)
c0105105:	c0 
c0105106:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c010510d:	c0 
c010510e:	c7 44 24 04 37 00 00 	movl   $0x37,0x4(%esp)
c0105115:	00 
c0105116:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c010511d:	e8 23 b3 ff ff       	call   c0100445 <__panic>
c0105122:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105125:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0105128:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010512b:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010512e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0105131:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0105134:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105137:	89 45 e0             	mov    %eax,-0x20(%ebp)
 * Insert the new element @elm *after* the element @listelm which
 * is already in the list.
 * */
static inline void
list_add_after(list_entry_t *listelm, list_entry_t *elm) {
    __list_add(elm, listelm, listelm->next);
c010513a:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010513d:	8b 40 04             	mov    0x4(%eax),%eax
c0105140:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0105143:	89 55 dc             	mov    %edx,-0x24(%ebp)
c0105146:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0105149:	89 55 d8             	mov    %edx,-0x28(%ebp)
c010514c:	89 45 d4             	mov    %eax,-0x2c(%ebp)
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 * */
static inline void
__list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) {
    prev->next = next->prev = elm;
c010514f:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0105152:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0105155:	89 10                	mov    %edx,(%eax)
c0105157:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c010515a:	8b 10                	mov    (%eax),%edx
c010515c:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010515f:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0105162:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0105165:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0105168:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c010516b:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010516e:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0105171:	89 10                	mov    %edx,(%eax)
}
c0105173:	90                   	nop
}
c0105174:	90                   	nop
}
c0105175:	90                   	nop
    //record the page access situlation
    /*LAB3 EXERCISE 2: YOUR CODE*/ 
    //(1)link the most recent arrival page at the back of the pra_list_head qeueue.
    //将最近到达的页面链接到 pra_list_head 队列的末尾
    list_add(head, entry);
    return 0;
c0105176:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010517b:	c9                   	leave  
c010517c:	c3                   	ret    

c010517d <_fifo_swap_out_victim>:
 * 
 * @return 返回0表示成功，其他值表示失败。
 */
static int
_fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick)
{
c010517d:	f3 0f 1e fb          	endbr32 
c0105181:	55                   	push   %ebp
c0105182:	89 e5                	mov    %esp,%ebp
c0105184:	83 ec 38             	sub    $0x38,%esp
     list_entry_t *head=(list_entry_t*) mm->sm_priv;
c0105187:	8b 45 08             	mov    0x8(%ebp),%eax
c010518a:	8b 40 14             	mov    0x14(%eax),%eax
c010518d:	89 45 f4             	mov    %eax,-0xc(%ebp)
         assert(head != NULL);
c0105190:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105194:	75 24                	jne    c01051ba <_fifo_swap_out_victim+0x3d>
c0105196:	c7 44 24 0c e3 9f 10 	movl   $0xc0109fe3,0xc(%esp)
c010519d:	c0 
c010519e:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c01051a5:	c0 
c01051a6:	c7 44 24 04 50 00 00 	movl   $0x50,0x4(%esp)
c01051ad:	00 
c01051ae:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c01051b5:	e8 8b b2 ff ff       	call   c0100445 <__panic>
     assert(in_tick==0);
c01051ba:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c01051be:	74 24                	je     c01051e4 <_fifo_swap_out_victim+0x67>
c01051c0:	c7 44 24 0c f0 9f 10 	movl   $0xc0109ff0,0xc(%esp)
c01051c7:	c0 
c01051c8:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c01051cf:	c0 
c01051d0:	c7 44 24 04 51 00 00 	movl   $0x51,0x4(%esp)
c01051d7:	00 
c01051d8:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c01051df:	e8 61 b2 ff ff       	call   c0100445 <__panic>
     /* Select the victim */
     /*LAB3 EXERCISE 2: YOUR CODE*/ 
     //(1)  unlink the  earliest arrival page in front of pra_list_head qeueue
     //(2)  assign the value of *ptr_page to the addr of this page
     //head->prev 获取链表中最先到达的页面
     list_entry_t *le = head->prev;
c01051e4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01051e7:	8b 00                	mov    (%eax),%eax
c01051e9:	89 45 f0             	mov    %eax,-0x10(%ebp)
     assert(head!=le);
c01051ec:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01051ef:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c01051f2:	75 24                	jne    c0105218 <_fifo_swap_out_victim+0x9b>
c01051f4:	c7 44 24 0c fb 9f 10 	movl   $0xc0109ffb,0xc(%esp)
c01051fb:	c0 
c01051fc:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c0105203:	c0 
c0105204:	c7 44 24 04 58 00 00 	movl   $0x58,0x4(%esp)
c010520b:	00 
c010520c:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c0105213:	e8 2d b2 ff ff       	call   c0100445 <__panic>
     struct Page *p = le2page(le, pra_page_link);
c0105218:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010521b:	83 e8 14             	sub    $0x14,%eax
c010521e:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0105221:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105224:	89 45 e8             	mov    %eax,-0x18(%ebp)
    __list_del(listelm->prev, listelm->next);
c0105227:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010522a:	8b 40 04             	mov    0x4(%eax),%eax
c010522d:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0105230:	8b 12                	mov    (%edx),%edx
c0105232:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c0105235:	89 45 e0             	mov    %eax,-0x20(%ebp)
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 * */
static inline void
__list_del(list_entry_t *prev, list_entry_t *next) {
    prev->next = next;
c0105238:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010523b:	8b 55 e0             	mov    -0x20(%ebp),%edx
c010523e:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0105241:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105244:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0105247:	89 10                	mov    %edx,(%eax)
}
c0105249:	90                   	nop
}
c010524a:	90                   	nop
     //使用 list_del 函数将该页面从链表中移除。
     list_del(le);
     assert(p != NULL);
c010524b:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c010524f:	75 24                	jne    c0105275 <_fifo_swap_out_victim+0xf8>
c0105251:	c7 44 24 0c 04 a0 10 	movl   $0xc010a004,0xc(%esp)
c0105258:	c0 
c0105259:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c0105260:	c0 
c0105261:	c7 44 24 04 5c 00 00 	movl   $0x5c,0x4(%esp)
c0105268:	00 
c0105269:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c0105270:	e8 d0 b1 ff ff       	call   c0100445 <__panic>
     //将移除的页面指针赋值给 *ptr_page
     *ptr_page = p;
c0105275:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105278:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010527b:	89 10                	mov    %edx,(%eax)
     
     return 0;
c010527d:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0105282:	c9                   	leave  
c0105283:	c3                   	ret    

c0105284 <_fifo_check_swap>:
 * 
 * 返回值:
 * - 0: 表示所有检查均通过。
 */
static int
_fifo_check_swap(void) {
c0105284:	f3 0f 1e fb          	endbr32 
c0105288:	55                   	push   %ebp
c0105289:	89 e5                	mov    %esp,%ebp
c010528b:	83 ec 18             	sub    $0x18,%esp
    // 写入虚拟页 c 并检查页面故障数
    cprintf("write Virt Page c in fifo_check_swap\n");
c010528e:	c7 04 24 10 a0 10 c0 	movl   $0xc010a010,(%esp)
c0105295:	e8 3f b0 ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x3000 = 0x0c;
c010529a:	b8 00 30 00 00       	mov    $0x3000,%eax
c010529f:	c6 00 0c             	movb   $0xc,(%eax)
    assert(pgfault_num==4);
c01052a2:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01052a7:	83 f8 04             	cmp    $0x4,%eax
c01052aa:	74 24                	je     c01052d0 <_fifo_check_swap+0x4c>
c01052ac:	c7 44 24 0c 36 a0 10 	movl   $0xc010a036,0xc(%esp)
c01052b3:	c0 
c01052b4:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c01052bb:	c0 
c01052bc:	c7 44 24 04 70 00 00 	movl   $0x70,0x4(%esp)
c01052c3:	00 
c01052c4:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c01052cb:	e8 75 b1 ff ff       	call   c0100445 <__panic>

    // 写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c01052d0:	c7 04 24 48 a0 10 c0 	movl   $0xc010a048,(%esp)
c01052d7:	e8 fd af ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x1000 = 0x0a;
c01052dc:	b8 00 10 00 00       	mov    $0x1000,%eax
c01052e1:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==4);
c01052e4:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01052e9:	83 f8 04             	cmp    $0x4,%eax
c01052ec:	74 24                	je     c0105312 <_fifo_check_swap+0x8e>
c01052ee:	c7 44 24 0c 36 a0 10 	movl   $0xc010a036,0xc(%esp)
c01052f5:	c0 
c01052f6:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c01052fd:	c0 
c01052fe:	c7 44 24 04 75 00 00 	movl   $0x75,0x4(%esp)
c0105305:	00 
c0105306:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c010530d:	e8 33 b1 ff ff       	call   c0100445 <__panic>

    // 写入虚拟页 d 并检查页面故障数
    cprintf("write Virt Page d in fifo_check_swap\n");
c0105312:	c7 04 24 70 a0 10 c0 	movl   $0xc010a070,(%esp)
c0105319:	e8 bb af ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x4000 = 0x0d;
c010531e:	b8 00 40 00 00       	mov    $0x4000,%eax
c0105323:	c6 00 0d             	movb   $0xd,(%eax)
    assert(pgfault_num==4);
c0105326:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c010532b:	83 f8 04             	cmp    $0x4,%eax
c010532e:	74 24                	je     c0105354 <_fifo_check_swap+0xd0>
c0105330:	c7 44 24 0c 36 a0 10 	movl   $0xc010a036,0xc(%esp)
c0105337:	c0 
c0105338:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c010533f:	c0 
c0105340:	c7 44 24 04 7a 00 00 	movl   $0x7a,0x4(%esp)
c0105347:	00 
c0105348:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c010534f:	e8 f1 b0 ff ff       	call   c0100445 <__panic>

    // 写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c0105354:	c7 04 24 98 a0 10 c0 	movl   $0xc010a098,(%esp)
c010535b:	e8 79 af ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c0105360:	b8 00 20 00 00       	mov    $0x2000,%eax
c0105365:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==4);
c0105368:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c010536d:	83 f8 04             	cmp    $0x4,%eax
c0105370:	74 24                	je     c0105396 <_fifo_check_swap+0x112>
c0105372:	c7 44 24 0c 36 a0 10 	movl   $0xc010a036,0xc(%esp)
c0105379:	c0 
c010537a:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c0105381:	c0 
c0105382:	c7 44 24 04 7f 00 00 	movl   $0x7f,0x4(%esp)
c0105389:	00 
c010538a:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c0105391:	e8 af b0 ff ff       	call   c0100445 <__panic>

    // 写入虚拟页 e 并检查页面故障数
    cprintf("write Virt Page e in fifo_check_swap\n");
c0105396:	c7 04 24 c0 a0 10 c0 	movl   $0xc010a0c0,(%esp)
c010539d:	e8 37 af ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x5000 = 0x0e;
c01053a2:	b8 00 50 00 00       	mov    $0x5000,%eax
c01053a7:	c6 00 0e             	movb   $0xe,(%eax)
    assert(pgfault_num==5);
c01053aa:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01053af:	83 f8 05             	cmp    $0x5,%eax
c01053b2:	74 24                	je     c01053d8 <_fifo_check_swap+0x154>
c01053b4:	c7 44 24 0c e6 a0 10 	movl   $0xc010a0e6,0xc(%esp)
c01053bb:	c0 
c01053bc:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c01053c3:	c0 
c01053c4:	c7 44 24 04 84 00 00 	movl   $0x84,0x4(%esp)
c01053cb:	00 
c01053cc:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c01053d3:	e8 6d b0 ff ff       	call   c0100445 <__panic>

    // 再次写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c01053d8:	c7 04 24 98 a0 10 c0 	movl   $0xc010a098,(%esp)
c01053df:	e8 f5 ae ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c01053e4:	b8 00 20 00 00       	mov    $0x2000,%eax
c01053e9:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==5);
c01053ec:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01053f1:	83 f8 05             	cmp    $0x5,%eax
c01053f4:	74 24                	je     c010541a <_fifo_check_swap+0x196>
c01053f6:	c7 44 24 0c e6 a0 10 	movl   $0xc010a0e6,0xc(%esp)
c01053fd:	c0 
c01053fe:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c0105405:	c0 
c0105406:	c7 44 24 04 89 00 00 	movl   $0x89,0x4(%esp)
c010540d:	00 
c010540e:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c0105415:	e8 2b b0 ff ff       	call   c0100445 <__panic>

    // 再次写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c010541a:	c7 04 24 48 a0 10 c0 	movl   $0xc010a048,(%esp)
c0105421:	e8 b3 ae ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x1000 = 0x0a;
c0105426:	b8 00 10 00 00       	mov    $0x1000,%eax
c010542b:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==6);
c010542e:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c0105433:	83 f8 06             	cmp    $0x6,%eax
c0105436:	74 24                	je     c010545c <_fifo_check_swap+0x1d8>
c0105438:	c7 44 24 0c f5 a0 10 	movl   $0xc010a0f5,0xc(%esp)
c010543f:	c0 
c0105440:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c0105447:	c0 
c0105448:	c7 44 24 04 8e 00 00 	movl   $0x8e,0x4(%esp)
c010544f:	00 
c0105450:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c0105457:	e8 e9 af ff ff       	call   c0100445 <__panic>

    // 再次写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c010545c:	c7 04 24 98 a0 10 c0 	movl   $0xc010a098,(%esp)
c0105463:	e8 71 ae ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c0105468:	b8 00 20 00 00       	mov    $0x2000,%eax
c010546d:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==7);
c0105470:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c0105475:	83 f8 07             	cmp    $0x7,%eax
c0105478:	74 24                	je     c010549e <_fifo_check_swap+0x21a>
c010547a:	c7 44 24 0c 04 a1 10 	movl   $0xc010a104,0xc(%esp)
c0105481:	c0 
c0105482:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c0105489:	c0 
c010548a:	c7 44 24 04 93 00 00 	movl   $0x93,0x4(%esp)
c0105491:	00 
c0105492:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c0105499:	e8 a7 af ff ff       	call   c0100445 <__panic>

    // 再次写入虚拟页 c 并检查页面故障数
    cprintf("write Virt Page c in fifo_check_swap\n");
c010549e:	c7 04 24 10 a0 10 c0 	movl   $0xc010a010,(%esp)
c01054a5:	e8 2f ae ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x3000 = 0x0c;
c01054aa:	b8 00 30 00 00       	mov    $0x3000,%eax
c01054af:	c6 00 0c             	movb   $0xc,(%eax)
    assert(pgfault_num==8);
c01054b2:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01054b7:	83 f8 08             	cmp    $0x8,%eax
c01054ba:	74 24                	je     c01054e0 <_fifo_check_swap+0x25c>
c01054bc:	c7 44 24 0c 13 a1 10 	movl   $0xc010a113,0xc(%esp)
c01054c3:	c0 
c01054c4:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c01054cb:	c0 
c01054cc:	c7 44 24 04 98 00 00 	movl   $0x98,0x4(%esp)
c01054d3:	00 
c01054d4:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c01054db:	e8 65 af ff ff       	call   c0100445 <__panic>

    // 再次写入虚拟页 d 并检查页面故障数
    cprintf("write Virt Page d in fifo_check_swap\n");
c01054e0:	c7 04 24 70 a0 10 c0 	movl   $0xc010a070,(%esp)
c01054e7:	e8 ed ad ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x4000 = 0x0d;
c01054ec:	b8 00 40 00 00       	mov    $0x4000,%eax
c01054f1:	c6 00 0d             	movb   $0xd,(%eax)
    assert(pgfault_num==9);
c01054f4:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01054f9:	83 f8 09             	cmp    $0x9,%eax
c01054fc:	74 24                	je     c0105522 <_fifo_check_swap+0x29e>
c01054fe:	c7 44 24 0c 22 a1 10 	movl   $0xc010a122,0xc(%esp)
c0105505:	c0 
c0105506:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c010550d:	c0 
c010550e:	c7 44 24 04 9d 00 00 	movl   $0x9d,0x4(%esp)
c0105515:	00 
c0105516:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c010551d:	e8 23 af ff ff       	call   c0100445 <__panic>

     // 再次写入虚拟页 e 并检查页面故障数
    cprintf("write Virt Page e in fifo_check_swap\n");
c0105522:	c7 04 24 c0 a0 10 c0 	movl   $0xc010a0c0,(%esp)
c0105529:	e8 ab ad ff ff       	call   c01002d9 <cprintf>
    *(unsigned char *)0x5000 = 0x0e;
c010552e:	b8 00 50 00 00       	mov    $0x5000,%eax
c0105533:	c6 00 0e             	movb   $0xe,(%eax)
    assert(pgfault_num==10);
c0105536:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c010553b:	83 f8 0a             	cmp    $0xa,%eax
c010553e:	74 24                	je     c0105564 <_fifo_check_swap+0x2e0>
c0105540:	c7 44 24 0c 31 a1 10 	movl   $0xc010a131,0xc(%esp)
c0105547:	c0 
c0105548:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c010554f:	c0 
c0105550:	c7 44 24 04 a2 00 00 	movl   $0xa2,0x4(%esp)
c0105557:	00 
c0105558:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c010555f:	e8 e1 ae ff ff       	call   c0100445 <__panic>

    // 再次写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c0105564:	c7 04 24 48 a0 10 c0 	movl   $0xc010a048,(%esp)
c010556b:	e8 69 ad ff ff       	call   c01002d9 <cprintf>
    assert(*(unsigned char *)0x1000 == 0x0a);
c0105570:	b8 00 10 00 00       	mov    $0x1000,%eax
c0105575:	0f b6 00             	movzbl (%eax),%eax
c0105578:	3c 0a                	cmp    $0xa,%al
c010557a:	74 24                	je     c01055a0 <_fifo_check_swap+0x31c>
c010557c:	c7 44 24 0c 44 a1 10 	movl   $0xc010a144,0xc(%esp)
c0105583:	c0 
c0105584:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c010558b:	c0 
c010558c:	c7 44 24 04 a6 00 00 	movl   $0xa6,0x4(%esp)
c0105593:	00 
c0105594:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c010559b:	e8 a5 ae ff ff       	call   c0100445 <__panic>
    *(unsigned char *)0x1000 = 0x0a;
c01055a0:	b8 00 10 00 00       	mov    $0x1000,%eax
c01055a5:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==11);
c01055a8:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01055ad:	83 f8 0b             	cmp    $0xb,%eax
c01055b0:	74 24                	je     c01055d6 <_fifo_check_swap+0x352>
c01055b2:	c7 44 24 0c 65 a1 10 	movl   $0xc010a165,0xc(%esp)
c01055b9:	c0 
c01055ba:	c7 44 24 08 ba 9f 10 	movl   $0xc0109fba,0x8(%esp)
c01055c1:	c0 
c01055c2:	c7 44 24 04 a8 00 00 	movl   $0xa8,0x4(%esp)
c01055c9:	00 
c01055ca:	c7 04 24 cf 9f 10 c0 	movl   $0xc0109fcf,(%esp)
c01055d1:	e8 6f ae ff ff       	call   c0100445 <__panic>
    return 0;
c01055d6:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01055db:	c9                   	leave  
c01055dc:	c3                   	ret    

c01055dd <_fifo_init>:


static int
_fifo_init(void)
{
c01055dd:	f3 0f 1e fb          	endbr32 
c01055e1:	55                   	push   %ebp
c01055e2:	89 e5                	mov    %esp,%ebp
    return 0;
c01055e4:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01055e9:	5d                   	pop    %ebp
c01055ea:	c3                   	ret    

c01055eb <_fifo_set_unswappable>:

static int
_fifo_set_unswappable(struct mm_struct *mm, uintptr_t addr)
{
c01055eb:	f3 0f 1e fb          	endbr32 
c01055ef:	55                   	push   %ebp
c01055f0:	89 e5                	mov    %esp,%ebp
    return 0;
c01055f2:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01055f7:	5d                   	pop    %ebp
c01055f8:	c3                   	ret    

c01055f9 <_fifo_tick_event>:

static int
_fifo_tick_event(struct mm_struct *mm)
{ return 0; }
c01055f9:	f3 0f 1e fb          	endbr32 
c01055fd:	55                   	push   %ebp
c01055fe:	89 e5                	mov    %esp,%ebp
c0105600:	b8 00 00 00 00       	mov    $0x0,%eax
c0105605:	5d                   	pop    %ebp
c0105606:	c3                   	ret    

c0105607 <pa2page>:
pa2page(uintptr_t pa) {
c0105607:	55                   	push   %ebp
c0105608:	89 e5                	mov    %esp,%ebp
c010560a:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c010560d:	8b 45 08             	mov    0x8(%ebp),%eax
c0105610:	c1 e8 0c             	shr    $0xc,%eax
c0105613:	89 c2                	mov    %eax,%edx
c0105615:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c010561a:	39 c2                	cmp    %eax,%edx
c010561c:	72 1c                	jb     c010563a <pa2page+0x33>
        panic("pa2page called with invalid pa");
c010561e:	c7 44 24 08 88 a1 10 	movl   $0xc010a188,0x8(%esp)
c0105625:	c0 
c0105626:	c7 44 24 04 5b 00 00 	movl   $0x5b,0x4(%esp)
c010562d:	00 
c010562e:	c7 04 24 a7 a1 10 c0 	movl   $0xc010a1a7,(%esp)
c0105635:	e8 0b ae ff ff       	call   c0100445 <__panic>
    return &pages[PPN(pa)];
c010563a:	a1 78 70 12 c0       	mov    0xc0127078,%eax
c010563f:	8b 55 08             	mov    0x8(%ebp),%edx
c0105642:	c1 ea 0c             	shr    $0xc,%edx
c0105645:	c1 e2 05             	shl    $0x5,%edx
c0105648:	01 d0                	add    %edx,%eax
}
c010564a:	c9                   	leave  
c010564b:	c3                   	ret    

c010564c <pde2page>:
pde2page(pde_t pde) {
c010564c:	55                   	push   %ebp
c010564d:	89 e5                	mov    %esp,%ebp
c010564f:	83 ec 18             	sub    $0x18,%esp
    return pa2page(PDE_ADDR(pde));
c0105652:	8b 45 08             	mov    0x8(%ebp),%eax
c0105655:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010565a:	89 04 24             	mov    %eax,(%esp)
c010565d:	e8 a5 ff ff ff       	call   c0105607 <pa2page>
}
c0105662:	c9                   	leave  
c0105663:	c3                   	ret    

c0105664 <mm_create>:
 * 它包括内存映射列表、页目录、映射缓存等重要信息
 * 
 * @return 分配并初始化后的`mm_struct`结构体指针，如果分配失败则返回NULL
 */
struct mm_struct *
mm_create(void) {
c0105664:	f3 0f 1e fb          	endbr32 
c0105668:	55                   	push   %ebp
c0105669:	89 e5                	mov    %esp,%ebp
c010566b:	83 ec 28             	sub    $0x28,%esp
    // 分配一个mm_struct结构体的空间
    struct mm_struct *mm = kmalloc(sizeof(struct mm_struct));
c010566e:	c7 04 24 18 00 00 00 	movl   $0x18,(%esp)
c0105675:	e8 e2 f8 ff ff       	call   c0104f5c <kmalloc>
c010567a:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查是否成功分配了内存
    if (mm != NULL) {
c010567d:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105681:	74 59                	je     c01056dc <mm_create+0x78>
        // 初始化内存映射列表
        list_init(&(mm->mmap_list));
c0105683:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105686:	89 45 f0             	mov    %eax,-0x10(%ebp)
    elm->prev = elm->next = elm;
c0105689:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010568c:	8b 55 f0             	mov    -0x10(%ebp),%edx
c010568f:	89 50 04             	mov    %edx,0x4(%eax)
c0105692:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105695:	8b 50 04             	mov    0x4(%eax),%edx
c0105698:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010569b:	89 10                	mov    %edx,(%eax)
}
c010569d:	90                   	nop
        // 设置映射缓存为NULL，表示尚未缓存任何映射
        mm->mmap_cache = NULL;
c010569e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01056a1:	c7 40 08 00 00 00 00 	movl   $0x0,0x8(%eax)
        // 设置页目录为NULL，表示尚未分配页目录
        mm->pgdir = NULL;
c01056a8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01056ab:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
        // 初始化映射计数为0，表示尚未创建任何内存映射
        mm->map_count = 0;
c01056b2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01056b5:	c7 40 10 00 00 00 00 	movl   $0x0,0x10(%eax)
        // 如果交换空间初始化成功，则为当前内存管理结构体进行交换空间初始化
        if (swap_init_ok) swap_init_mm(mm);
c01056bc:	a1 10 70 12 c0       	mov    0xc0127010,%eax
c01056c1:	85 c0                	test   %eax,%eax
c01056c3:	74 0d                	je     c01056d2 <mm_create+0x6e>
c01056c5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01056c8:	89 04 24             	mov    %eax,(%esp)
c01056cb:	e8 0f 0e 00 00       	call   c01064df <swap_init_mm>
c01056d0:	eb 0a                	jmp    c01056dc <mm_create+0x78>
        else mm->sm_priv = NULL;
c01056d2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01056d5:	c7 40 14 00 00 00 00 	movl   $0x0,0x14(%eax)
    }
    // 返回分配并初始化后的内存管理结构体指针
    return mm;
c01056dc:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01056df:	c9                   	leave  
c01056e0:	c3                   	ret    

c01056e1 <vma_create>:
 * @param vm_flags 虚拟内存区域的标志，表示内存区域的权限和特性。
 * 
 * @return 返回指向新创建的vma_struct结构体的指针，如果内存分配失败，则返回NULL。
 */
struct vma_struct *
vma_create(uintptr_t vm_start, uintptr_t vm_end, uint32_t vm_flags) {
c01056e1:	f3 0f 1e fb          	endbr32 
c01056e5:	55                   	push   %ebp
c01056e6:	89 e5                	mov    %esp,%ebp
c01056e8:	83 ec 28             	sub    $0x28,%esp
    // 分配vma_struct结构体所需的内存空间
    struct vma_struct *vma = kmalloc(sizeof(struct vma_struct));
c01056eb:	c7 04 24 18 00 00 00 	movl   $0x18,(%esp)
c01056f2:	e8 65 f8 ff ff       	call   c0104f5c <kmalloc>
c01056f7:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查内存是否成功分配
    if (vma != NULL) {
c01056fa:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01056fe:	74 1b                	je     c010571b <vma_create+0x3a>
        // 初始化vma_struct的成员变量
        vma->vm_start = vm_start;
c0105700:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105703:	8b 55 08             	mov    0x8(%ebp),%edx
c0105706:	89 50 04             	mov    %edx,0x4(%eax)
        vma->vm_end = vm_end;
c0105709:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010570c:	8b 55 0c             	mov    0xc(%ebp),%edx
c010570f:	89 50 08             	mov    %edx,0x8(%eax)
        vma->vm_flags = vm_flags;
c0105712:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105715:	8b 55 10             	mov    0x10(%ebp),%edx
c0105718:	89 50 0c             	mov    %edx,0xc(%eax)
    }
    // 返回指向新创建的vma_struct结构体的指针，或在内存分配失败时返回NULL
    return vma;
c010571b:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010571e:	c9                   	leave  
c010571f:	c3                   	ret    

c0105720 <find_vma>:
 * 此函数首先检查mmap_cache是否包含所需的VMA，以加速查找过程
 * 如果mmap_cache未命中，则遍历VMA列表，直到找到包含给定地址的VMA或确定不存在这样的VMA
 * 如果找到了合适的VMA，它将更新mmap_cache以供后续查找使用
 */
struct vma_struct *
find_vma(struct mm_struct *mm, uintptr_t addr) {
c0105720:	f3 0f 1e fb          	endbr32 
c0105724:	55                   	push   %ebp
c0105725:	89 e5                	mov    %esp,%ebp
c0105727:	83 ec 20             	sub    $0x20,%esp
    struct vma_struct *vma = NULL;// 初始化VMA指针为NULL
c010572a:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    if (mm != NULL) {// 检查传入的内存描述符是否有效
c0105731:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0105735:	0f 84 95 00 00 00    	je     c01057d0 <find_vma+0xb0>
        // 检查mmap_cache是否包含所需的VMA
        vma = mm->mmap_cache;
c010573b:	8b 45 08             	mov    0x8(%ebp),%eax
c010573e:	8b 40 08             	mov    0x8(%eax),%eax
c0105741:	89 45 fc             	mov    %eax,-0x4(%ebp)
        if (!(vma != NULL && vma->vm_start <= addr && vma->vm_end > addr)) {
c0105744:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c0105748:	74 16                	je     c0105760 <find_vma+0x40>
c010574a:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010574d:	8b 40 04             	mov    0x4(%eax),%eax
c0105750:	39 45 0c             	cmp    %eax,0xc(%ebp)
c0105753:	72 0b                	jb     c0105760 <find_vma+0x40>
c0105755:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0105758:	8b 40 08             	mov    0x8(%eax),%eax
c010575b:	39 45 0c             	cmp    %eax,0xc(%ebp)
c010575e:	72 61                	jb     c01057c1 <find_vma+0xa1>
                // 如果mmap_cache未命中，则开始遍历VMA列表
                bool found = 0;// 初始化找到标志为0
c0105760:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%ebp)
                // 获取VMA列表的头指针
                list_entry_t *list = &(mm->mmap_list), *le = list;
c0105767:	8b 45 08             	mov    0x8(%ebp),%eax
c010576a:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010576d:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105770:	89 45 f4             	mov    %eax,-0xc(%ebp)
                while ((le = list_next(le)) != list) { // 遍历VMA列表
c0105773:	eb 28                	jmp    c010579d <find_vma+0x7d>
                    vma = le2vma(le, list_link);// 将链表项转换为VMA结构
c0105775:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105778:	83 e8 10             	sub    $0x10,%eax
c010577b:	89 45 fc             	mov    %eax,-0x4(%ebp)
                    // 检查当前VMA是否包含给定地址
                    if (vma->vm_start<=addr && addr < vma->vm_end) {
c010577e:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0105781:	8b 40 04             	mov    0x4(%eax),%eax
c0105784:	39 45 0c             	cmp    %eax,0xc(%ebp)
c0105787:	72 14                	jb     c010579d <find_vma+0x7d>
c0105789:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010578c:	8b 40 08             	mov    0x8(%eax),%eax
c010578f:	39 45 0c             	cmp    %eax,0xc(%ebp)
c0105792:	73 09                	jae    c010579d <find_vma+0x7d>
                        found = 1;// 找到合适的VMA
c0105794:	c7 45 f8 01 00 00 00 	movl   $0x1,-0x8(%ebp)
                        break;// 结束循环
c010579b:	eb 17                	jmp    c01057b4 <find_vma+0x94>
c010579d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01057a0:	89 45 ec             	mov    %eax,-0x14(%ebp)
    return listelm->next;
c01057a3:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01057a6:	8b 40 04             	mov    0x4(%eax),%eax
                while ((le = list_next(le)) != list) { // 遍历VMA列表
c01057a9:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01057ac:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01057af:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c01057b2:	75 c1                	jne    c0105775 <find_vma+0x55>
                    }
                }
                if (!found) {// 如果未找到合适的VMA
c01057b4:	83 7d f8 00          	cmpl   $0x0,-0x8(%ebp)
c01057b8:	75 07                	jne    c01057c1 <find_vma+0xa1>
                    vma = NULL;// 将VMA指针设置为NULL
c01057ba:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
                }
        }
        // 如果找到了合适的VMA，更新mmap_cache
        if (vma != NULL) {
c01057c1:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c01057c5:	74 09                	je     c01057d0 <find_vma+0xb0>
            mm->mmap_cache = vma;// 更新mmap_cache以加速后续查找
c01057c7:	8b 45 08             	mov    0x8(%ebp),%eax
c01057ca:	8b 55 fc             	mov    -0x4(%ebp),%edx
c01057cd:	89 50 08             	mov    %edx,0x8(%eax)
        }
    }
    return vma;
c01057d0:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c01057d3:	c9                   	leave  
c01057d4:	c3                   	ret    

c01057d5 <check_vma_overlap>:
 * 
 * @param prev 指向前一个虚拟内存区域（VMA）的结构体指针
 * @param next 指向后一个虚拟内存区域（VMA）的结构体指针
 */
static inline void
check_vma_overlap(struct vma_struct *prev, struct vma_struct *next) {
c01057d5:	55                   	push   %ebp
c01057d6:	89 e5                	mov    %esp,%ebp
c01057d8:	83 ec 18             	sub    $0x18,%esp
    assert(prev->vm_start < prev->vm_end);// 确保前一个VMA的地址范围是有效的
c01057db:	8b 45 08             	mov    0x8(%ebp),%eax
c01057de:	8b 50 04             	mov    0x4(%eax),%edx
c01057e1:	8b 45 08             	mov    0x8(%ebp),%eax
c01057e4:	8b 40 08             	mov    0x8(%eax),%eax
c01057e7:	39 c2                	cmp    %eax,%edx
c01057e9:	72 24                	jb     c010580f <check_vma_overlap+0x3a>
c01057eb:	c7 44 24 0c b5 a1 10 	movl   $0xc010a1b5,0xc(%esp)
c01057f2:	c0 
c01057f3:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c01057fa:	c0 
c01057fb:	c7 44 24 04 a0 00 00 	movl   $0xa0,0x4(%esp)
c0105802:	00 
c0105803:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c010580a:	e8 36 ac ff ff       	call   c0100445 <__panic>
    assert(prev->vm_end <= next->vm_start);// 确保两个VMA之间没有重叠
c010580f:	8b 45 08             	mov    0x8(%ebp),%eax
c0105812:	8b 50 08             	mov    0x8(%eax),%edx
c0105815:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105818:	8b 40 04             	mov    0x4(%eax),%eax
c010581b:	39 c2                	cmp    %eax,%edx
c010581d:	76 24                	jbe    c0105843 <check_vma_overlap+0x6e>
c010581f:	c7 44 24 0c f8 a1 10 	movl   $0xc010a1f8,0xc(%esp)
c0105826:	c0 
c0105827:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c010582e:	c0 
c010582f:	c7 44 24 04 a1 00 00 	movl   $0xa1,0x4(%esp)
c0105836:	00 
c0105837:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c010583e:	e8 02 ac ff ff       	call   c0100445 <__panic>
    assert(next->vm_start < next->vm_end);// 确保后一个VMA的地址范围是有效的
c0105843:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105846:	8b 50 04             	mov    0x4(%eax),%edx
c0105849:	8b 45 0c             	mov    0xc(%ebp),%eax
c010584c:	8b 40 08             	mov    0x8(%eax),%eax
c010584f:	39 c2                	cmp    %eax,%edx
c0105851:	72 24                	jb     c0105877 <check_vma_overlap+0xa2>
c0105853:	c7 44 24 0c 17 a2 10 	movl   $0xc010a217,0xc(%esp)
c010585a:	c0 
c010585b:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105862:	c0 
c0105863:	c7 44 24 04 a2 00 00 	movl   $0xa2,0x4(%esp)
c010586a:	00 
c010586b:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105872:	e8 ce ab ff ff       	call   c0100445 <__panic>
}
c0105877:	90                   	nop
c0105878:	c9                   	leave  
c0105879:	c3                   	ret    

c010587a <insert_vma_struct>:
 *
 * @param mm 指向内存描述符结构 `struct mm_struct` 的指针，表示一个进程的内存空间。
 * @param vma 指向要插入的VMA结构 `struct vma_struct` 的指针，描述一个内存区域。
 */
void
insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) {
c010587a:	f3 0f 1e fb          	endbr32 
c010587e:	55                   	push   %ebp
c010587f:	89 e5                	mov    %esp,%ebp
c0105881:	83 ec 48             	sub    $0x48,%esp
    // 断言VMA结构的起始地址小于结束地址，确保VMA结构的有效性。
    assert(vma->vm_start < vma->vm_end);
c0105884:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105887:	8b 50 04             	mov    0x4(%eax),%edx
c010588a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010588d:	8b 40 08             	mov    0x8(%eax),%eax
c0105890:	39 c2                	cmp    %eax,%edx
c0105892:	72 24                	jb     c01058b8 <insert_vma_struct+0x3e>
c0105894:	c7 44 24 0c 35 a2 10 	movl   $0xc010a235,0xc(%esp)
c010589b:	c0 
c010589c:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c01058a3:	c0 
c01058a4:	c7 44 24 04 b3 00 00 	movl   $0xb3,0x4(%esp)
c01058ab:	00 
c01058ac:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c01058b3:	e8 8d ab ff ff       	call   c0100445 <__panic>
    // 指向内存描述符中的VMA链表。
    list_entry_t *list = &(mm->mmap_list);
c01058b8:	8b 45 08             	mov    0x8(%ebp),%eax
c01058bb:	89 45 ec             	mov    %eax,-0x14(%ebp)
     // 遍历链表以找到新VMA结构的正确插入位置。
    list_entry_t *le_prev = list, *le_next;
c01058be:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01058c1:	89 45 f4             	mov    %eax,-0xc(%ebp)

        list_entry_t *le = list;
c01058c4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01058c7:	89 45 f0             	mov    %eax,-0x10(%ebp)
        // 遍历链表以找到新VMA结构的正确插入位置
        while ((le = list_next(le)) != list) {
c01058ca:	eb 1f                	jmp    c01058eb <insert_vma_struct+0x71>
            struct vma_struct *mmap_prev = le2vma(le, list_link);
c01058cc:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01058cf:	83 e8 10             	sub    $0x10,%eax
c01058d2:	89 45 e8             	mov    %eax,-0x18(%ebp)
            // 如果当前VMA的起始地址大于新VMA的起始地址，则跳出循环
            if (mmap_prev->vm_start > vma->vm_start) {
c01058d5:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01058d8:	8b 50 04             	mov    0x4(%eax),%edx
c01058db:	8b 45 0c             	mov    0xc(%ebp),%eax
c01058de:	8b 40 04             	mov    0x4(%eax),%eax
c01058e1:	39 c2                	cmp    %eax,%edx
c01058e3:	77 1f                	ja     c0105904 <insert_vma_struct+0x8a>
                break;
            }
            le_prev = le;
c01058e5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01058e8:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01058eb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01058ee:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01058f1:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01058f4:	8b 40 04             	mov    0x4(%eax),%eax
        while ((le = list_next(le)) != list) {
c01058f7:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01058fa:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01058fd:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0105900:	75 ca                	jne    c01058cc <insert_vma_struct+0x52>
c0105902:	eb 01                	jmp    c0105905 <insert_vma_struct+0x8b>
                break;
c0105904:	90                   	nop
c0105905:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105908:	89 45 dc             	mov    %eax,-0x24(%ebp)
c010590b:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010590e:	8b 40 04             	mov    0x4(%eax),%eax
        }
    // 获取下一个链表项
    le_next = list_next(le_prev);
c0105911:	89 45 e4             	mov    %eax,-0x1c(%ebp)

    /* check overlap */
    // 检查前一个VMA结构是否与新VMA结构重叠
    if (le_prev != list) {
c0105914:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105917:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c010591a:	74 15                	je     c0105931 <insert_vma_struct+0xb7>
        check_vma_overlap(le2vma(le_prev, list_link), vma);
c010591c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010591f:	8d 50 f0             	lea    -0x10(%eax),%edx
c0105922:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105925:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105929:	89 14 24             	mov    %edx,(%esp)
c010592c:	e8 a4 fe ff ff       	call   c01057d5 <check_vma_overlap>
    }
    // 检查下一个VMA结构是否与新VMA结构重叠
    if (le_next != list) {
c0105931:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0105934:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0105937:	74 15                	je     c010594e <insert_vma_struct+0xd4>
        check_vma_overlap(vma, le2vma(le_next, list_link));
c0105939:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010593c:	83 e8 10             	sub    $0x10,%eax
c010593f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105943:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105946:	89 04 24             	mov    %eax,(%esp)
c0105949:	e8 87 fe ff ff       	call   c01057d5 <check_vma_overlap>
    }
    // 设置VMA结构所属的内存描述符
    vma->vm_mm = mm;
c010594e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105951:	8b 55 08             	mov    0x8(%ebp),%edx
c0105954:	89 10                	mov    %edx,(%eax)
    // 将新VMA结构插入链表
    list_add_after(le_prev, &(vma->list_link));
c0105956:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105959:	8d 50 10             	lea    0x10(%eax),%edx
c010595c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010595f:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0105962:	89 55 d4             	mov    %edx,-0x2c(%ebp)
    __list_add(elm, listelm, listelm->next);
c0105965:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0105968:	8b 40 04             	mov    0x4(%eax),%eax
c010596b:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010596e:	89 55 d0             	mov    %edx,-0x30(%ebp)
c0105971:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0105974:	89 55 cc             	mov    %edx,-0x34(%ebp)
c0105977:	89 45 c8             	mov    %eax,-0x38(%ebp)
    prev->next = next->prev = elm;
c010597a:	8b 45 c8             	mov    -0x38(%ebp),%eax
c010597d:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0105980:	89 10                	mov    %edx,(%eax)
c0105982:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0105985:	8b 10                	mov    (%eax),%edx
c0105987:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010598a:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c010598d:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0105990:	8b 55 c8             	mov    -0x38(%ebp),%edx
c0105993:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0105996:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0105999:	8b 55 cc             	mov    -0x34(%ebp),%edx
c010599c:	89 10                	mov    %edx,(%eax)
}
c010599e:	90                   	nop
}
c010599f:	90                   	nop
    // 增加内存描述符中的映射计数
    mm->map_count ++;
c01059a0:	8b 45 08             	mov    0x8(%ebp),%eax
c01059a3:	8b 40 10             	mov    0x10(%eax),%eax
c01059a6:	8d 50 01             	lea    0x1(%eax),%edx
c01059a9:	8b 45 08             	mov    0x8(%ebp),%eax
c01059ac:	89 50 10             	mov    %edx,0x10(%eax)
}
c01059af:	90                   	nop
c01059b0:	c9                   	leave  
c01059b1:	c3                   	ret    

c01059b2 <mm_destroy>:
 * 此函数遍历并销毁与内存管理结构（mm_struct）关联的所有虚拟内存区域（VMA），
 * 然后释放内存管理结构本身所占用的内存。这样做是为了确保在销毁内存管理结构之前，
 * 所有相关的资源都被正确地释放。
 */
void
mm_destroy(struct mm_struct *mm) {
c01059b2:	f3 0f 1e fb          	endbr32 
c01059b6:	55                   	push   %ebp
c01059b7:	89 e5                	mov    %esp,%ebp
c01059b9:	83 ec 38             	sub    $0x38,%esp
    // 获取内存映射列表的头指针
    list_entry_t *list = &(mm->mmap_list), *le;
c01059bc:	8b 45 08             	mov    0x8(%ebp),%eax
c01059bf:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历内存映射列表，直到回到起点
    while ((le = list_next(list)) != list) {
c01059c2:	eb 40                	jmp    c0105a04 <mm_destroy+0x52>
c01059c4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01059c7:	89 45 ec             	mov    %eax,-0x14(%ebp)
    __list_del(listelm->prev, listelm->next);
c01059ca:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01059cd:	8b 40 04             	mov    0x4(%eax),%eax
c01059d0:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01059d3:	8b 12                	mov    (%edx),%edx
c01059d5:	89 55 e8             	mov    %edx,-0x18(%ebp)
c01059d8:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    prev->next = next;
c01059db:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01059de:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01059e1:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c01059e4:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01059e7:	8b 55 e8             	mov    -0x18(%ebp),%edx
c01059ea:	89 10                	mov    %edx,(%eax)
}
c01059ec:	90                   	nop
}
c01059ed:	90                   	nop
        // 从列表中删除当前虚拟内存区域的项
        list_del(le);
        // 释放虚拟内存区域结构的内存
        kfree(le2vma(le, list_link),sizeof(struct vma_struct));  //kfree vma        
c01059ee:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01059f1:	83 e8 10             	sub    $0x10,%eax
c01059f4:	c7 44 24 04 18 00 00 	movl   $0x18,0x4(%esp)
c01059fb:	00 
c01059fc:	89 04 24             	mov    %eax,(%esp)
c01059ff:	e8 fc f5 ff ff       	call   c0105000 <kfree>
c0105a04:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105a07:	89 45 e0             	mov    %eax,-0x20(%ebp)
    return listelm->next;
c0105a0a:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105a0d:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(list)) != list) {
c0105a10:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0105a13:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105a16:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0105a19:	75 a9                	jne    c01059c4 <mm_destroy+0x12>
    }
    // 释放内存管理结构本身的内存
    kfree(mm, sizeof(struct mm_struct)); //kfree mm
c0105a1b:	c7 44 24 04 18 00 00 	movl   $0x18,0x4(%esp)
c0105a22:	00 
c0105a23:	8b 45 08             	mov    0x8(%ebp),%eax
c0105a26:	89 04 24             	mov    %eax,(%esp)
c0105a29:	e8 d2 f5 ff ff       	call   c0105000 <kfree>
    // 将指针设置为NULL，表示该结构已被销毁
    mm=NULL;
c0105a2e:	c7 45 08 00 00 00 00 	movl   $0x0,0x8(%ebp)
}
c0105a35:	90                   	nop
c0105a36:	c9                   	leave  
c0105a37:	c3                   	ret    

c0105a38 <vmm_init>:
/**
 * 初始化虚拟内存管理(VMM)系统。
 * 此函数通过执行一系列检查来确保VMM系统可以正确初始化和运行。
 */
void
vmm_init(void) {
c0105a38:	f3 0f 1e fb          	endbr32 
c0105a3c:	55                   	push   %ebp
c0105a3d:	89 e5                	mov    %esp,%ebp
c0105a3f:	83 ec 08             	sub    $0x8,%esp
    // 检查VMM系统的状态和环境，以确保其能够正常工作。
    check_vmm();
c0105a42:	e8 03 00 00 00       	call   c0105a4a <check_vmm>
}
c0105a47:	90                   	nop
c0105a48:	c9                   	leave  
c0105a49:	c3                   	ret    

c0105a4a <check_vmm>:
 * 此函数的目的是确保虚拟内存管理系统的正确性通过检查内存区域结构（VMA）、页面故障处理以及免费页面计数的 consistency 来实现
 * 它首先保存当前的免费页面数量，然后执行与 VMA 和页面故障相关的检查，最后确认免费页面数量未发生变化
 * 这是为了确保在检查过程中，内存状态没有因为错误或意外的修改而改变，从而验证内存管理的正确性
 */
static void
check_vmm(void) {
c0105a4a:	f3 0f 1e fb          	endbr32 
c0105a4e:	55                   	push   %ebp
c0105a4f:	89 e5                	mov    %esp,%ebp
c0105a51:	83 ec 28             	sub    $0x28,%esp
    // 保存当前的免费页面数量，用于后续的 consistency 检查
    size_t nr_free_pages_store = nr_free_pages();
c0105a54:	e8 ec dd ff ff       	call   c0103845 <nr_free_pages>
c0105a59:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查虚拟内存区域（VMA）结构的正确性
    check_vma_struct();
c0105a5c:	e8 42 00 00 00       	call   c0105aa3 <check_vma_struct>
    // 检查页面故障处理的正确性
    check_pgfault();
c0105a61:	e8 01 05 00 00       	call   c0105f67 <check_pgfault>
    // 确保在检查过程中免费页面数量未发生变化，表明内存管理操作是正确的
    assert(nr_free_pages_store == nr_free_pages());
c0105a66:	e8 da dd ff ff       	call   c0103845 <nr_free_pages>
c0105a6b:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0105a6e:	74 24                	je     c0105a94 <check_vmm+0x4a>
c0105a70:	c7 44 24 0c 54 a2 10 	movl   $0xc010a254,0xc(%esp)
c0105a77:	c0 
c0105a78:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105a7f:	c0 
c0105a80:	c7 44 24 04 0e 01 00 	movl   $0x10e,0x4(%esp)
c0105a87:	00 
c0105a88:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105a8f:	e8 b1 a9 ff ff       	call   c0100445 <__panic>
    // 如果所有检查都通过，输出成功信息
    cprintf("check_vmm() succeeded.\n");
c0105a94:	c7 04 24 7b a2 10 c0 	movl   $0xc010a27b,(%esp)
c0105a9b:	e8 39 a8 ff ff       	call   c01002d9 <cprintf>
}
c0105aa0:	90                   	nop
c0105aa1:	c9                   	leave  
c0105aa2:	c3                   	ret    

c0105aa3 <check_vma_struct>:

//测试虚拟内存区域（VMA）结构的创建、插入和查找功能。
static void
check_vma_struct(void) {
c0105aa3:	f3 0f 1e fb          	endbr32 
c0105aa7:	55                   	push   %ebp
c0105aa8:	89 e5                	mov    %esp,%ebp
c0105aaa:	83 ec 68             	sub    $0x68,%esp
    // 记录当前空闲页面数量
    size_t nr_free_pages_store = nr_free_pages();
c0105aad:	e8 93 dd ff ff       	call   c0103845 <nr_free_pages>
c0105ab2:	89 45 ec             	mov    %eax,-0x14(%ebp)

    struct mm_struct *mm = mm_create();// 创建内存管理结构 mm
c0105ab5:	e8 aa fb ff ff       	call   c0105664 <mm_create>
c0105aba:	89 45 e8             	mov    %eax,-0x18(%ebp)
    assert(mm != NULL);// 确保 mm 不为 NULL
c0105abd:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0105ac1:	75 24                	jne    c0105ae7 <check_vma_struct+0x44>
c0105ac3:	c7 44 24 0c 93 a2 10 	movl   $0xc010a293,0xc(%esp)
c0105aca:	c0 
c0105acb:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105ad2:	c0 
c0105ad3:	c7 44 24 04 1a 01 00 	movl   $0x11a,0x4(%esp)
c0105ada:	00 
c0105adb:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105ae2:	e8 5e a9 ff ff       	call   c0100445 <__panic>

    int step1 = 10, step2 = step1 * 10;// 定义两个步骤的步数
c0105ae7:	c7 45 e4 0a 00 00 00 	movl   $0xa,-0x1c(%ebp)
c0105aee:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0105af1:	89 d0                	mov    %edx,%eax
c0105af3:	c1 e0 02             	shl    $0x2,%eax
c0105af6:	01 d0                	add    %edx,%eax
c0105af8:	01 c0                	add    %eax,%eax
c0105afa:	89 45 e0             	mov    %eax,-0x20(%ebp)

    int i;
    for (i = step1; i >= 1; i --) {// 第一步：创建并插入10个VMA
c0105afd:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0105b00:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0105b03:	eb 6f                	jmp    c0105b74 <check_vma_struct+0xd1>
        // 创建 VMA 结构
        struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0);
c0105b05:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105b08:	89 d0                	mov    %edx,%eax
c0105b0a:	c1 e0 02             	shl    $0x2,%eax
c0105b0d:	01 d0                	add    %edx,%eax
c0105b0f:	83 c0 02             	add    $0x2,%eax
c0105b12:	89 c1                	mov    %eax,%ecx
c0105b14:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105b17:	89 d0                	mov    %edx,%eax
c0105b19:	c1 e0 02             	shl    $0x2,%eax
c0105b1c:	01 d0                	add    %edx,%eax
c0105b1e:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105b25:	00 
c0105b26:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c0105b2a:	89 04 24             	mov    %eax,(%esp)
c0105b2d:	e8 af fb ff ff       	call   c01056e1 <vma_create>
c0105b32:	89 45 bc             	mov    %eax,-0x44(%ebp)
        assert(vma != NULL);// 确保 VMA 不为 NULL
c0105b35:	83 7d bc 00          	cmpl   $0x0,-0x44(%ebp)
c0105b39:	75 24                	jne    c0105b5f <check_vma_struct+0xbc>
c0105b3b:	c7 44 24 0c 9e a2 10 	movl   $0xc010a29e,0xc(%esp)
c0105b42:	c0 
c0105b43:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105b4a:	c0 
c0105b4b:	c7 44 24 04 22 01 00 	movl   $0x122,0x4(%esp)
c0105b52:	00 
c0105b53:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105b5a:	e8 e6 a8 ff ff       	call   c0100445 <__panic>
        insert_vma_struct(mm, vma); //将 VMA 插入到 mm 中
c0105b5f:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0105b62:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105b66:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105b69:	89 04 24             	mov    %eax,(%esp)
c0105b6c:	e8 09 fd ff ff       	call   c010587a <insert_vma_struct>
    for (i = step1; i >= 1; i --) {// 第一步：创建并插入10个VMA
c0105b71:	ff 4d f4             	decl   -0xc(%ebp)
c0105b74:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105b78:	7f 8b                	jg     c0105b05 <check_vma_struct+0x62>
    }

    for (i = step1 + 1; i <= step2; i ++) {// 第二步：创建并插入90个VMA
c0105b7a:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0105b7d:	40                   	inc    %eax
c0105b7e:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0105b81:	eb 6f                	jmp    c0105bf2 <check_vma_struct+0x14f>
        // 创建 VMA 结构
        struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0);
c0105b83:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105b86:	89 d0                	mov    %edx,%eax
c0105b88:	c1 e0 02             	shl    $0x2,%eax
c0105b8b:	01 d0                	add    %edx,%eax
c0105b8d:	83 c0 02             	add    $0x2,%eax
c0105b90:	89 c1                	mov    %eax,%ecx
c0105b92:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105b95:	89 d0                	mov    %edx,%eax
c0105b97:	c1 e0 02             	shl    $0x2,%eax
c0105b9a:	01 d0                	add    %edx,%eax
c0105b9c:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105ba3:	00 
c0105ba4:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c0105ba8:	89 04 24             	mov    %eax,(%esp)
c0105bab:	e8 31 fb ff ff       	call   c01056e1 <vma_create>
c0105bb0:	89 45 c0             	mov    %eax,-0x40(%ebp)
        assert(vma != NULL);// 确保 VMA 不为 NULL
c0105bb3:	83 7d c0 00          	cmpl   $0x0,-0x40(%ebp)
c0105bb7:	75 24                	jne    c0105bdd <check_vma_struct+0x13a>
c0105bb9:	c7 44 24 0c 9e a2 10 	movl   $0xc010a29e,0xc(%esp)
c0105bc0:	c0 
c0105bc1:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105bc8:	c0 
c0105bc9:	c7 44 24 04 29 01 00 	movl   $0x129,0x4(%esp)
c0105bd0:	00 
c0105bd1:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105bd8:	e8 68 a8 ff ff       	call   c0100445 <__panic>
        insert_vma_struct(mm, vma);// 将 VMA 插入到 mm 中
c0105bdd:	8b 45 c0             	mov    -0x40(%ebp),%eax
c0105be0:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105be4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105be7:	89 04 24             	mov    %eax,(%esp)
c0105bea:	e8 8b fc ff ff       	call   c010587a <insert_vma_struct>
    for (i = step1 + 1; i <= step2; i ++) {// 第二步：创建并插入90个VMA
c0105bef:	ff 45 f4             	incl   -0xc(%ebp)
c0105bf2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105bf5:	3b 45 e0             	cmp    -0x20(%ebp),%eax
c0105bf8:	7e 89                	jle    c0105b83 <check_vma_struct+0xe0>
    }
    // 获取 VMA 链表的第一个节点
    list_entry_t *le = list_next(&(mm->mmap_list));
c0105bfa:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105bfd:	89 45 b8             	mov    %eax,-0x48(%ebp)
c0105c00:	8b 45 b8             	mov    -0x48(%ebp),%eax
c0105c03:	8b 40 04             	mov    0x4(%eax),%eax
c0105c06:	89 45 f0             	mov    %eax,-0x10(%ebp)

    for (i = 1; i <= step2; i ++) {// 验证插入顺序
c0105c09:	c7 45 f4 01 00 00 00 	movl   $0x1,-0xc(%ebp)
c0105c10:	e9 96 00 00 00       	jmp    c0105cab <check_vma_struct+0x208>
        assert(le != &(mm->mmap_list));// 确保节点不为空
c0105c15:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105c18:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0105c1b:	75 24                	jne    c0105c41 <check_vma_struct+0x19e>
c0105c1d:	c7 44 24 0c aa a2 10 	movl   $0xc010a2aa,0xc(%esp)
c0105c24:	c0 
c0105c25:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105c2c:	c0 
c0105c2d:	c7 44 24 04 30 01 00 	movl   $0x130,0x4(%esp)
c0105c34:	00 
c0105c35:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105c3c:	e8 04 a8 ff ff       	call   c0100445 <__panic>
        struct vma_struct *mmap = le2vma(le, list_link);// 将链表节点转换为 VMA 结构
c0105c41:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105c44:	83 e8 10             	sub    $0x10,%eax
c0105c47:	89 45 c4             	mov    %eax,-0x3c(%ebp)
        // 确认 VMA 的起始和结束地址
        assert(mmap->vm_start == i * 5 && mmap->vm_end == i * 5 + 2);
c0105c4a:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0105c4d:	8b 48 04             	mov    0x4(%eax),%ecx
c0105c50:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105c53:	89 d0                	mov    %edx,%eax
c0105c55:	c1 e0 02             	shl    $0x2,%eax
c0105c58:	01 d0                	add    %edx,%eax
c0105c5a:	39 c1                	cmp    %eax,%ecx
c0105c5c:	75 17                	jne    c0105c75 <check_vma_struct+0x1d2>
c0105c5e:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0105c61:	8b 48 08             	mov    0x8(%eax),%ecx
c0105c64:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105c67:	89 d0                	mov    %edx,%eax
c0105c69:	c1 e0 02             	shl    $0x2,%eax
c0105c6c:	01 d0                	add    %edx,%eax
c0105c6e:	83 c0 02             	add    $0x2,%eax
c0105c71:	39 c1                	cmp    %eax,%ecx
c0105c73:	74 24                	je     c0105c99 <check_vma_struct+0x1f6>
c0105c75:	c7 44 24 0c c4 a2 10 	movl   $0xc010a2c4,0xc(%esp)
c0105c7c:	c0 
c0105c7d:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105c84:	c0 
c0105c85:	c7 44 24 04 33 01 00 	movl   $0x133,0x4(%esp)
c0105c8c:	00 
c0105c8d:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105c94:	e8 ac a7 ff ff       	call   c0100445 <__panic>
c0105c99:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105c9c:	89 45 b4             	mov    %eax,-0x4c(%ebp)
c0105c9f:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0105ca2:	8b 40 04             	mov    0x4(%eax),%eax
        le = list_next(le);// 移动到下一个节点
c0105ca5:	89 45 f0             	mov    %eax,-0x10(%ebp)
    for (i = 1; i <= step2; i ++) {// 验证插入顺序
c0105ca8:	ff 45 f4             	incl   -0xc(%ebp)
c0105cab:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105cae:	3b 45 e0             	cmp    -0x20(%ebp),%eax
c0105cb1:	0f 8e 5e ff ff ff    	jle    c0105c15 <check_vma_struct+0x172>
    }

    for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA
c0105cb7:	c7 45 f4 05 00 00 00 	movl   $0x5,-0xc(%ebp)
c0105cbe:	e9 cb 01 00 00       	jmp    c0105e8e <check_vma_struct+0x3eb>
        struct vma_struct *vma1 = find_vma(mm, i);// 查找地址 i 处的 VMA
c0105cc3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105cc6:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105cca:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105ccd:	89 04 24             	mov    %eax,(%esp)
c0105cd0:	e8 4b fa ff ff       	call   c0105720 <find_vma>
c0105cd5:	89 45 d8             	mov    %eax,-0x28(%ebp)
        assert(vma1 != NULL);// 确保找到 VMA
c0105cd8:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c0105cdc:	75 24                	jne    c0105d02 <check_vma_struct+0x25f>
c0105cde:	c7 44 24 0c f9 a2 10 	movl   $0xc010a2f9,0xc(%esp)
c0105ce5:	c0 
c0105ce6:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105ced:	c0 
c0105cee:	c7 44 24 04 39 01 00 	movl   $0x139,0x4(%esp)
c0105cf5:	00 
c0105cf6:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105cfd:	e8 43 a7 ff ff       	call   c0100445 <__panic>
        // 查找地址 i + 1 处的 VMA
        struct vma_struct *vma2 = find_vma(mm, i+1);
c0105d02:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105d05:	40                   	inc    %eax
c0105d06:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105d0a:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105d0d:	89 04 24             	mov    %eax,(%esp)
c0105d10:	e8 0b fa ff ff       	call   c0105720 <find_vma>
c0105d15:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        assert(vma2 != NULL);// 确保找到 VMA
c0105d18:	83 7d d4 00          	cmpl   $0x0,-0x2c(%ebp)
c0105d1c:	75 24                	jne    c0105d42 <check_vma_struct+0x29f>
c0105d1e:	c7 44 24 0c 06 a3 10 	movl   $0xc010a306,0xc(%esp)
c0105d25:	c0 
c0105d26:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105d2d:	c0 
c0105d2e:	c7 44 24 04 3c 01 00 	movl   $0x13c,0x4(%esp)
c0105d35:	00 
c0105d36:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105d3d:	e8 03 a7 ff ff       	call   c0100445 <__panic>
        // 查找地址 i + 2 处的 VMA
        struct vma_struct *vma3 = find_vma(mm, i+2);
c0105d42:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105d45:	83 c0 02             	add    $0x2,%eax
c0105d48:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105d4c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105d4f:	89 04 24             	mov    %eax,(%esp)
c0105d52:	e8 c9 f9 ff ff       	call   c0105720 <find_vma>
c0105d57:	89 45 d0             	mov    %eax,-0x30(%ebp)
        assert(vma3 == NULL);// 确保未找到 VMA
c0105d5a:	83 7d d0 00          	cmpl   $0x0,-0x30(%ebp)
c0105d5e:	74 24                	je     c0105d84 <check_vma_struct+0x2e1>
c0105d60:	c7 44 24 0c 13 a3 10 	movl   $0xc010a313,0xc(%esp)
c0105d67:	c0 
c0105d68:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105d6f:	c0 
c0105d70:	c7 44 24 04 3f 01 00 	movl   $0x13f,0x4(%esp)
c0105d77:	00 
c0105d78:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105d7f:	e8 c1 a6 ff ff       	call   c0100445 <__panic>
        // 查找地址 i + 3 处的 VMA
        struct vma_struct *vma4 = find_vma(mm, i+3);
c0105d84:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105d87:	83 c0 03             	add    $0x3,%eax
c0105d8a:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105d8e:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105d91:	89 04 24             	mov    %eax,(%esp)
c0105d94:	e8 87 f9 ff ff       	call   c0105720 <find_vma>
c0105d99:	89 45 cc             	mov    %eax,-0x34(%ebp)
        assert(vma4 == NULL);// 确保未找到 VMA
c0105d9c:	83 7d cc 00          	cmpl   $0x0,-0x34(%ebp)
c0105da0:	74 24                	je     c0105dc6 <check_vma_struct+0x323>
c0105da2:	c7 44 24 0c 20 a3 10 	movl   $0xc010a320,0xc(%esp)
c0105da9:	c0 
c0105daa:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105db1:	c0 
c0105db2:	c7 44 24 04 42 01 00 	movl   $0x142,0x4(%esp)
c0105db9:	00 
c0105dba:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105dc1:	e8 7f a6 ff ff       	call   c0100445 <__panic>
        // 查找地址 i + 4 处的 VMA
        struct vma_struct *vma5 = find_vma(mm, i+4);
c0105dc6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105dc9:	83 c0 04             	add    $0x4,%eax
c0105dcc:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105dd0:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105dd3:	89 04 24             	mov    %eax,(%esp)
c0105dd6:	e8 45 f9 ff ff       	call   c0105720 <find_vma>
c0105ddb:	89 45 c8             	mov    %eax,-0x38(%ebp)
        assert(vma5 == NULL);// 确保未找到 VMA
c0105dde:	83 7d c8 00          	cmpl   $0x0,-0x38(%ebp)
c0105de2:	74 24                	je     c0105e08 <check_vma_struct+0x365>
c0105de4:	c7 44 24 0c 2d a3 10 	movl   $0xc010a32d,0xc(%esp)
c0105deb:	c0 
c0105dec:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105df3:	c0 
c0105df4:	c7 44 24 04 45 01 00 	movl   $0x145,0x4(%esp)
c0105dfb:	00 
c0105dfc:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105e03:	e8 3d a6 ff ff       	call   c0100445 <__panic>
        // 确认 VMA1 的起始和结束地址
        assert(vma1->vm_start == i  && vma1->vm_end == i  + 2);
c0105e08:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0105e0b:	8b 50 04             	mov    0x4(%eax),%edx
c0105e0e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105e11:	39 c2                	cmp    %eax,%edx
c0105e13:	75 10                	jne    c0105e25 <check_vma_struct+0x382>
c0105e15:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0105e18:	8b 40 08             	mov    0x8(%eax),%eax
c0105e1b:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105e1e:	83 c2 02             	add    $0x2,%edx
c0105e21:	39 d0                	cmp    %edx,%eax
c0105e23:	74 24                	je     c0105e49 <check_vma_struct+0x3a6>
c0105e25:	c7 44 24 0c 3c a3 10 	movl   $0xc010a33c,0xc(%esp)
c0105e2c:	c0 
c0105e2d:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105e34:	c0 
c0105e35:	c7 44 24 04 47 01 00 	movl   $0x147,0x4(%esp)
c0105e3c:	00 
c0105e3d:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105e44:	e8 fc a5 ff ff       	call   c0100445 <__panic>
        // 确认 VMA2 的起始和结束地址
        assert(vma2->vm_start == i  && vma2->vm_end == i  + 2);
c0105e49:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0105e4c:	8b 50 04             	mov    0x4(%eax),%edx
c0105e4f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105e52:	39 c2                	cmp    %eax,%edx
c0105e54:	75 10                	jne    c0105e66 <check_vma_struct+0x3c3>
c0105e56:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0105e59:	8b 40 08             	mov    0x8(%eax),%eax
c0105e5c:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105e5f:	83 c2 02             	add    $0x2,%edx
c0105e62:	39 d0                	cmp    %edx,%eax
c0105e64:	74 24                	je     c0105e8a <check_vma_struct+0x3e7>
c0105e66:	c7 44 24 0c 6c a3 10 	movl   $0xc010a36c,0xc(%esp)
c0105e6d:	c0 
c0105e6e:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105e75:	c0 
c0105e76:	c7 44 24 04 49 01 00 	movl   $0x149,0x4(%esp)
c0105e7d:	00 
c0105e7e:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105e85:	e8 bb a5 ff ff       	call   c0100445 <__panic>
    for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA
c0105e8a:	83 45 f4 05          	addl   $0x5,-0xc(%ebp)
c0105e8e:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0105e91:	89 d0                	mov    %edx,%eax
c0105e93:	c1 e0 02             	shl    $0x2,%eax
c0105e96:	01 d0                	add    %edx,%eax
c0105e98:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0105e9b:	0f 8e 22 fe ff ff    	jle    c0105cc3 <check_vma_struct+0x220>
    }
    // 检查小于5的地址范围内是否存在 VMA
    for (i =4; i>=0; i--) {
c0105ea1:	c7 45 f4 04 00 00 00 	movl   $0x4,-0xc(%ebp)
c0105ea8:	eb 6f                	jmp    c0105f19 <check_vma_struct+0x476>
        // 查找地址 i 处的 VMA
        struct vma_struct *vma_below_5= find_vma(mm,i);
c0105eaa:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105ead:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105eb1:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105eb4:	89 04 24             	mov    %eax,(%esp)
c0105eb7:	e8 64 f8 ff ff       	call   c0105720 <find_vma>
c0105ebc:	89 45 dc             	mov    %eax,-0x24(%ebp)
        if (vma_below_5 != NULL ) {// 如果找到 VMA
c0105ebf:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0105ec3:	74 27                	je     c0105eec <check_vma_struct+0x449>
           cprintf("vma_below_5: i %x, start %x, end %x\n",i, vma_below_5->vm_start, vma_below_5->vm_end); 
c0105ec5:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0105ec8:	8b 50 08             	mov    0x8(%eax),%edx
c0105ecb:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0105ece:	8b 40 04             	mov    0x4(%eax),%eax
c0105ed1:	89 54 24 0c          	mov    %edx,0xc(%esp)
c0105ed5:	89 44 24 08          	mov    %eax,0x8(%esp)
c0105ed9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105edc:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105ee0:	c7 04 24 9c a3 10 c0 	movl   $0xc010a39c,(%esp)
c0105ee7:	e8 ed a3 ff ff       	call   c01002d9 <cprintf>
        }
        assert(vma_below_5 == NULL);// 确保未找到 VMA
c0105eec:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0105ef0:	74 24                	je     c0105f16 <check_vma_struct+0x473>
c0105ef2:	c7 44 24 0c c1 a3 10 	movl   $0xc010a3c1,0xc(%esp)
c0105ef9:	c0 
c0105efa:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105f01:	c0 
c0105f02:	c7 44 24 04 52 01 00 	movl   $0x152,0x4(%esp)
c0105f09:	00 
c0105f0a:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105f11:	e8 2f a5 ff ff       	call   c0100445 <__panic>
    for (i =4; i>=0; i--) {
c0105f16:	ff 4d f4             	decl   -0xc(%ebp)
c0105f19:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105f1d:	79 8b                	jns    c0105eaa <check_vma_struct+0x407>
    }

    mm_destroy(mm);// 销毁 mm 结构
c0105f1f:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105f22:	89 04 24             	mov    %eax,(%esp)
c0105f25:	e8 88 fa ff ff       	call   c01059b2 <mm_destroy>

    // 确保释放的页面数量与初始记录一致
    assert(nr_free_pages_store == nr_free_pages());
c0105f2a:	e8 16 d9 ff ff       	call   c0103845 <nr_free_pages>
c0105f2f:	39 45 ec             	cmp    %eax,-0x14(%ebp)
c0105f32:	74 24                	je     c0105f58 <check_vma_struct+0x4b5>
c0105f34:	c7 44 24 0c 54 a2 10 	movl   $0xc010a254,0xc(%esp)
c0105f3b:	c0 
c0105f3c:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105f43:	c0 
c0105f44:	c7 44 24 04 58 01 00 	movl   $0x158,0x4(%esp)
c0105f4b:	00 
c0105f4c:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105f53:	e8 ed a4 ff ff       	call   c0100445 <__panic>
    // 输出成功信息
    cprintf("check_vma_struct() succeeded!\n");
c0105f58:	c7 04 24 d8 a3 10 c0 	movl   $0xc010a3d8,(%esp)
c0105f5f:	e8 75 a3 ff ff       	call   c01002d9 <cprintf>
}
c0105f64:	90                   	nop
c0105f65:	c9                   	leave  
c0105f66:	c3                   	ret    

c0105f67 <check_pgfault>:
struct mm_struct *check_mm_struct;

// check_pgfault - check correctness of pgfault handler
// 检查页故障处理的正确性
static void
check_pgfault(void) {
c0105f67:	f3 0f 1e fb          	endbr32 
c0105f6b:	55                   	push   %ebp
c0105f6c:	89 e5                	mov    %esp,%ebp
c0105f6e:	83 ec 38             	sub    $0x38,%esp
    // 保存当前空闲页面的数量，用于后续检查
    size_t nr_free_pages_store = nr_free_pages();
c0105f71:	e8 cf d8 ff ff       	call   c0103845 <nr_free_pages>
c0105f76:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 创建内存管理结构体
    check_mm_struct = mm_create();
c0105f79:	e8 e6 f6 ff ff       	call   c0105664 <mm_create>
c0105f7e:	a3 84 70 12 c0       	mov    %eax,0xc0127084
    // 确保内存管理结构体创建成功
    assert(check_mm_struct != NULL);
c0105f83:	a1 84 70 12 c0       	mov    0xc0127084,%eax
c0105f88:	85 c0                	test   %eax,%eax
c0105f8a:	75 24                	jne    c0105fb0 <check_pgfault+0x49>
c0105f8c:	c7 44 24 0c f7 a3 10 	movl   $0xc010a3f7,0xc(%esp)
c0105f93:	c0 
c0105f94:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105f9b:	c0 
c0105f9c:	c7 44 24 04 68 01 00 	movl   $0x168,0x4(%esp)
c0105fa3:	00 
c0105fa4:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105fab:	e8 95 a4 ff ff       	call   c0100445 <__panic>
    // 将新创建的内存管理结构体赋值给局部变量mm
    struct mm_struct *mm = check_mm_struct;
c0105fb0:	a1 84 70 12 c0       	mov    0xc0127084,%eax
c0105fb5:	89 45 e8             	mov    %eax,-0x18(%ebp)
    // 将引导程序的页目录复制到新创建的内存管理结构体中
    pde_t *pgdir = mm->pgdir = boot_pgdir;
c0105fb8:	8b 15 e0 39 12 c0    	mov    0xc01239e0,%edx
c0105fbe:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105fc1:	89 50 0c             	mov    %edx,0xc(%eax)
c0105fc4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105fc7:	8b 40 0c             	mov    0xc(%eax),%eax
c0105fca:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    // 确保页目录的第0项是空的
    assert(pgdir[0] == 0);
c0105fcd:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0105fd0:	8b 00                	mov    (%eax),%eax
c0105fd2:	85 c0                	test   %eax,%eax
c0105fd4:	74 24                	je     c0105ffa <check_pgfault+0x93>
c0105fd6:	c7 44 24 0c 0f a4 10 	movl   $0xc010a40f,0xc(%esp)
c0105fdd:	c0 
c0105fde:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0105fe5:	c0 
c0105fe6:	c7 44 24 04 6e 01 00 	movl   $0x16e,0x4(%esp)
c0105fed:	00 
c0105fee:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0105ff5:	e8 4b a4 ff ff       	call   c0100445 <__panic>
    // 创建一个虚拟内存区域结构体，具有写权限
    struct vma_struct *vma = vma_create(0, PTSIZE, VM_WRITE);
c0105ffa:	c7 44 24 08 02 00 00 	movl   $0x2,0x8(%esp)
c0106001:	00 
c0106002:	c7 44 24 04 00 00 40 	movl   $0x400000,0x4(%esp)
c0106009:	00 
c010600a:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0106011:	e8 cb f6 ff ff       	call   c01056e1 <vma_create>
c0106016:	89 45 e0             	mov    %eax,-0x20(%ebp)
    // 确保虚拟内存区域结构体创建成功
    assert(vma != NULL);
c0106019:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c010601d:	75 24                	jne    c0106043 <check_pgfault+0xdc>
c010601f:	c7 44 24 0c 9e a2 10 	movl   $0xc010a29e,0xc(%esp)
c0106026:	c0 
c0106027:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c010602e:	c0 
c010602f:	c7 44 24 04 72 01 00 	movl   $0x172,0x4(%esp)
c0106036:	00 
c0106037:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c010603e:	e8 02 a4 ff ff       	call   c0100445 <__panic>
    // 将虚拟内存区域结构体插入到内存管理结构体中
    insert_vma_struct(mm, vma);
c0106043:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0106046:	89 44 24 04          	mov    %eax,0x4(%esp)
c010604a:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010604d:	89 04 24             	mov    %eax,(%esp)
c0106050:	e8 25 f8 ff ff       	call   c010587a <insert_vma_struct>
    // 定义一个地址，用于访问虚拟内存
    uintptr_t addr = 0x100;
c0106055:	c7 45 dc 00 01 00 00 	movl   $0x100,-0x24(%ebp)
    // 确保通过该地址可以找到之前插入的虚拟内存区域
    assert(find_vma(mm, addr) == vma);
c010605c:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010605f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106063:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106066:	89 04 24             	mov    %eax,(%esp)
c0106069:	e8 b2 f6 ff ff       	call   c0105720 <find_vma>
c010606e:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c0106071:	74 24                	je     c0106097 <check_pgfault+0x130>
c0106073:	c7 44 24 0c 1d a4 10 	movl   $0xc010a41d,0xc(%esp)
c010607a:	c0 
c010607b:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c0106082:	c0 
c0106083:	c7 44 24 04 78 01 00 	movl   $0x178,0x4(%esp)
c010608a:	00 
c010608b:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c0106092:	e8 ae a3 ff ff       	call   c0100445 <__panic>
    // 初始化一个累加器，用于校验写入的数据
    int i, sum = 0;
c0106097:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    // 写入数据到虚拟内存，并累加
    for (i = 0; i < 100; i ++) {
c010609e:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c01060a5:	eb 16                	jmp    c01060bd <check_pgfault+0x156>
        *(char *)(addr + i) = i;
c01060a7:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01060aa:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01060ad:	01 d0                	add    %edx,%eax
c01060af:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01060b2:	88 10                	mov    %dl,(%eax)
        sum += i;
c01060b4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01060b7:	01 45 f0             	add    %eax,-0x10(%ebp)
    for (i = 0; i < 100; i ++) {
c01060ba:	ff 45 f4             	incl   -0xc(%ebp)
c01060bd:	83 7d f4 63          	cmpl   $0x63,-0xc(%ebp)
c01060c1:	7e e4                	jle    c01060a7 <check_pgfault+0x140>
    }
    // 读取虚拟内存中的数据，并减去，最终结果应为0
    for (i = 0; i < 100; i ++) {
c01060c3:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c01060ca:	eb 14                	jmp    c01060e0 <check_pgfault+0x179>
        sum -= *(char *)(addr + i);
c01060cc:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01060cf:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01060d2:	01 d0                	add    %edx,%eax
c01060d4:	0f b6 00             	movzbl (%eax),%eax
c01060d7:	0f be c0             	movsbl %al,%eax
c01060da:	29 45 f0             	sub    %eax,-0x10(%ebp)
    for (i = 0; i < 100; i ++) {
c01060dd:	ff 45 f4             	incl   -0xc(%ebp)
c01060e0:	83 7d f4 63          	cmpl   $0x63,-0xc(%ebp)
c01060e4:	7e e6                	jle    c01060cc <check_pgfault+0x165>
    }
    // 确保累加器的值为0，证明数据读写正确
    assert(sum == 0);
c01060e6:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01060ea:	74 24                	je     c0106110 <check_pgfault+0x1a9>
c01060ec:	c7 44 24 0c 37 a4 10 	movl   $0xc010a437,0xc(%esp)
c01060f3:	c0 
c01060f4:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c01060fb:	c0 
c01060fc:	c7 44 24 04 85 01 00 	movl   $0x185,0x4(%esp)
c0106103:	00 
c0106104:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c010610b:	e8 35 a3 ff ff       	call   c0100445 <__panic>
    // 移除页目录中的相应页面
    page_remove(pgdir, ROUNDDOWN(addr, PGSIZE));
c0106110:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0106113:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0106116:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0106119:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010611e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106122:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106125:	89 04 24             	mov    %eax,(%esp)
c0106128:	e8 39 df ff ff       	call   c0104066 <page_remove>
    // 释放第0项页目录对应的页面
    free_page(pde2page(pgdir[0]));
c010612d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106130:	8b 00                	mov    (%eax),%eax
c0106132:	89 04 24             	mov    %eax,(%esp)
c0106135:	e8 12 f5 ff ff       	call   c010564c <pde2page>
c010613a:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0106141:	00 
c0106142:	89 04 24             	mov    %eax,(%esp)
c0106145:	e8 c4 d6 ff ff       	call   c010380e <free_pages>
    // 将页目录的第0项设置为空
    pgdir[0] = 0;
c010614a:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010614d:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
    // 将内存管理结构体中的页目录设置为空
    mm->pgdir = NULL;
c0106153:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106156:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
    // 销毁内存管理结构体
    mm_destroy(mm);
c010615d:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106160:	89 04 24             	mov    %eax,(%esp)
c0106163:	e8 4a f8 ff ff       	call   c01059b2 <mm_destroy>
    // 将检查用的内存管理结构体设置为空
    check_mm_struct = NULL;
c0106168:	c7 05 84 70 12 c0 00 	movl   $0x0,0xc0127084
c010616f:	00 00 00 
    // 确保空闲页面的数量没有变化，证明内存管理正确
    assert(nr_free_pages_store == nr_free_pages());
c0106172:	e8 ce d6 ff ff       	call   c0103845 <nr_free_pages>
c0106177:	39 45 ec             	cmp    %eax,-0x14(%ebp)
c010617a:	74 24                	je     c01061a0 <check_pgfault+0x239>
c010617c:	c7 44 24 0c 54 a2 10 	movl   $0xc010a254,0xc(%esp)
c0106183:	c0 
c0106184:	c7 44 24 08 d3 a1 10 	movl   $0xc010a1d3,0x8(%esp)
c010618b:	c0 
c010618c:	c7 44 24 04 93 01 00 	movl   $0x193,0x4(%esp)
c0106193:	00 
c0106194:	c7 04 24 e8 a1 10 c0 	movl   $0xc010a1e8,(%esp)
c010619b:	e8 a5 a2 ff ff       	call   c0100445 <__panic>
    // 打印成功信息
    cprintf("check_pgfault() succeeded!\n");
c01061a0:	c7 04 24 40 a4 10 c0 	movl   $0xc010a440,(%esp)
c01061a7:	e8 2d a1 ff ff       	call   c01002d9 <cprintf>
}
c01061ac:	90                   	nop
c01061ad:	c9                   	leave  
c01061ae:	c3                   	ret    

c01061af <do_pgfault>:
 * @param addr 引发页面错误的线性地址。
 * 
 * @return 成功返回0，失败返回负错误码。
 */
int
do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
c01061af:	f3 0f 1e fb          	endbr32 
c01061b3:	55                   	push   %ebp
c01061b4:	89 e5                	mov    %esp,%ebp
c01061b6:	83 ec 38             	sub    $0x38,%esp
    int ret = -E_INVAL;// 初始化返回值为无效错误
c01061b9:	c7 45 f4 fd ff ff ff 	movl   $0xfffffffd,-0xc(%ebp)
    //try to find a vma which include addr
    // 尝试找到包含 addr 的 vma
    struct vma_struct *vma = find_vma(mm, addr);
c01061c0:	8b 45 10             	mov    0x10(%ebp),%eax
c01061c3:	89 44 24 04          	mov    %eax,0x4(%esp)
c01061c7:	8b 45 08             	mov    0x8(%ebp),%eax
c01061ca:	89 04 24             	mov    %eax,(%esp)
c01061cd:	e8 4e f5 ff ff       	call   c0105720 <find_vma>
c01061d2:	89 45 ec             	mov    %eax,-0x14(%ebp)

    pgfault_num++;// 增加页面错误计数
c01061d5:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01061da:	40                   	inc    %eax
c01061db:	a3 0c 70 12 c0       	mov    %eax,0xc012700c
    // 检查 addr 是否在 mm 的 vma 范围内
    //If the addr is in the range of a mm's vma?
    if (vma == NULL || vma->vm_start > addr) {
c01061e0:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c01061e4:	74 0b                	je     c01061f1 <do_pgfault+0x42>
c01061e6:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01061e9:	8b 40 04             	mov    0x4(%eax),%eax
c01061ec:	39 45 10             	cmp    %eax,0x10(%ebp)
c01061ef:	73 18                	jae    c0106209 <do_pgfault+0x5a>
        cprintf("not valid addr %x, and  can not find it in vma\n", addr);
c01061f1:	8b 45 10             	mov    0x10(%ebp),%eax
c01061f4:	89 44 24 04          	mov    %eax,0x4(%esp)
c01061f8:	c7 04 24 5c a4 10 c0 	movl   $0xc010a45c,(%esp)
c01061ff:	e8 d5 a0 ff ff       	call   c01002d9 <cprintf>
        goto failed;// 跳转到错误处理部分
c0106204:	e9 ba 01 00 00       	jmp    c01063c3 <do_pgfault+0x214>
    }
    //check the error_code
    // 检查错误代码
    switch (error_code & 3) {
c0106209:	8b 45 0c             	mov    0xc(%ebp),%eax
c010620c:	83 e0 03             	and    $0x3,%eax
c010620f:	85 c0                	test   %eax,%eax
c0106211:	74 34                	je     c0106247 <do_pgfault+0x98>
c0106213:	83 f8 01             	cmp    $0x1,%eax
c0106216:	74 1e                	je     c0106236 <do_pgfault+0x87>
    default:
            /* 默认错误代码标志：3 (W/R=1, P=1): 写操作，存在 */
            /* error code flag : default is 3 ( W/R=1, P=1): write, present */
    case 2: /* error code flag : (W/R=1, P=0): write, not present */
            /* 错误代码标志：(W/R=1, P=0): 写操作，不存在 */
        if (!(vma->vm_flags & VM_WRITE)) {
c0106218:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010621b:	8b 40 0c             	mov    0xc(%eax),%eax
c010621e:	83 e0 02             	and    $0x2,%eax
c0106221:	85 c0                	test   %eax,%eax
c0106223:	75 40                	jne    c0106265 <do_pgfault+0xb6>
            cprintf("do_pgfault failed: error code flag = write AND not present, but the addr's vma cannot write\n");
c0106225:	c7 04 24 8c a4 10 c0 	movl   $0xc010a48c,(%esp)
c010622c:	e8 a8 a0 ff ff       	call   c01002d9 <cprintf>
            goto failed;// 跳转到错误处理部分
c0106231:	e9 8d 01 00 00       	jmp    c01063c3 <do_pgfault+0x214>
        }
        break;
    case 1: /* error code flag : (W/R=0, P=1): read, present */
            /* 错误代码标志：(W/R=0, P=1): 读操作，存在 */
        cprintf("do_pgfault failed: error code flag = read AND present\n");
c0106236:	c7 04 24 ec a4 10 c0 	movl   $0xc010a4ec,(%esp)
c010623d:	e8 97 a0 ff ff       	call   c01002d9 <cprintf>
        goto failed;// 跳转到错误处理部分
c0106242:	e9 7c 01 00 00       	jmp    c01063c3 <do_pgfault+0x214>
    case 0: /* error code flag : (W/R=0, P=0): read, not present */
             /* 错误代码标志：(W/R=0, P=0): 读操作，不存在 */
        if (!(vma->vm_flags & (VM_READ | VM_EXEC))) {
c0106247:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010624a:	8b 40 0c             	mov    0xc(%eax),%eax
c010624d:	83 e0 05             	and    $0x5,%eax
c0106250:	85 c0                	test   %eax,%eax
c0106252:	75 12                	jne    c0106266 <do_pgfault+0xb7>
            cprintf("do_pgfault failed: error code flag = read AND not present, but the addr's vma cannot read or exec\n");
c0106254:	c7 04 24 24 a5 10 c0 	movl   $0xc010a524,(%esp)
c010625b:	e8 79 a0 ff ff       	call   c01002d9 <cprintf>
            goto failed;// 跳转到错误处理部分
c0106260:	e9 5e 01 00 00       	jmp    c01063c3 <do_pgfault+0x214>
        break;
c0106265:	90                   	nop
    /* 如果 (写入已存在的地址) 或
     *    (写入不存在的地址且地址可写) 或
     *    (读取不存在的地址且地址可读)
     * 则继续处理
     */
    uint32_t perm = PTE_U;// 初始化权限标志为用户可访问
c0106266:	c7 45 f0 04 00 00 00 	movl   $0x4,-0x10(%ebp)
    if (vma->vm_flags & VM_WRITE) {
c010626d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106270:	8b 40 0c             	mov    0xc(%eax),%eax
c0106273:	83 e0 02             	and    $0x2,%eax
c0106276:	85 c0                	test   %eax,%eax
c0106278:	74 04                	je     c010627e <do_pgfault+0xcf>
        perm |= PTE_W;// 如果 vma 可写，则设置写权限
c010627a:	83 4d f0 02          	orl    $0x2,-0x10(%ebp)
    }
    addr = ROUNDDOWN(addr, PGSIZE);// 将地址对齐到页边界
c010627e:	8b 45 10             	mov    0x10(%ebp),%eax
c0106281:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0106284:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106287:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010628c:	89 45 10             	mov    %eax,0x10(%ebp)

    ret = -E_NO_MEM;// 初始化返回值为内存不足错误
c010628f:	c7 45 f4 fc ff ff ff 	movl   $0xfffffffc,-0xc(%ebp)

    pte_t *ptep=NULL;
c0106296:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
#endif
    // try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT.
    // (notice the 3th parameter '1')
    // 尝试找到一个页表项 pte，如果包含该 pte 的页表不存在，则创建一个页表。
    // 注意第三个参数 '1' 表示如果需要，可以创建新的页表。
    if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) {
c010629d:	8b 45 08             	mov    0x8(%ebp),%eax
c01062a0:	8b 40 0c             	mov    0xc(%eax),%eax
c01062a3:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c01062aa:	00 
c01062ab:	8b 55 10             	mov    0x10(%ebp),%edx
c01062ae:	89 54 24 04          	mov    %edx,0x4(%esp)
c01062b2:	89 04 24             	mov    %eax,(%esp)
c01062b5:	e8 b0 db ff ff       	call   c0103e6a <get_pte>
c01062ba:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c01062bd:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c01062c1:	75 11                	jne    c01062d4 <do_pgfault+0x125>
        cprintf("get_pte in do_pgfault failed\n");// 输出错误信息
c01062c3:	c7 04 24 87 a5 10 c0 	movl   $0xc010a587,(%esp)
c01062ca:	e8 0a a0 ff ff       	call   c01002d9 <cprintf>
        goto failed;// 跳转到错误处理部分
c01062cf:	e9 ef 00 00 00       	jmp    c01063c3 <do_pgfault+0x214>
    }
    // 如果页表项 pte 的物理地址不存在，则分配一页内存并映射物理地址与逻辑地址
    if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr
c01062d4:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01062d7:	8b 00                	mov    (%eax),%eax
c01062d9:	85 c0                	test   %eax,%eax
c01062db:	75 35                	jne    c0106312 <do_pgfault+0x163>
        if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) {
c01062dd:	8b 45 08             	mov    0x8(%ebp),%eax
c01062e0:	8b 40 0c             	mov    0xc(%eax),%eax
c01062e3:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01062e6:	89 54 24 08          	mov    %edx,0x8(%esp)
c01062ea:	8b 55 10             	mov    0x10(%ebp),%edx
c01062ed:	89 54 24 04          	mov    %edx,0x4(%esp)
c01062f1:	89 04 24             	mov    %eax,(%esp)
c01062f4:	e8 d4 de ff ff       	call   c01041cd <pgdir_alloc_page>
c01062f9:	85 c0                	test   %eax,%eax
c01062fb:	0f 85 bb 00 00 00    	jne    c01063bc <do_pgfault+0x20d>
            cprintf("pgdir_alloc_page in do_pgfault failed\n");// 输出错误信息
c0106301:	c7 04 24 a8 a5 10 c0 	movl   $0xc010a5a8,(%esp)
c0106308:	e8 cc 9f ff ff       	call   c01002d9 <cprintf>
            goto failed;// 跳转到错误处理部分
c010630d:	e9 b1 00 00 00       	jmp    c01063c3 <do_pgfault+0x214>
    }
    else { // if this pte is a swap entry, then load data from disk to a page with phy addr
           // and call page_insert to map the phy addr with logical addr
           // 如果页表项 pte 是一个交换项，则从磁盘加载数据到
           //一个具有物理地址的页面，并映射物理地址与逻辑地址
        if(swap_init_ok) {// 检查交换初始化是否成功
c0106312:	a1 10 70 12 c0       	mov    0xc0127010,%eax
c0106317:	85 c0                	test   %eax,%eax
c0106319:	0f 84 86 00 00 00    	je     c01063a5 <do_pgfault+0x1f6>
            struct Page *page=NULL;// 声明一个页面指针
c010631f:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
            if ((ret = swap_in(mm, addr, &page)) != 0) {
c0106326:	8d 45 e0             	lea    -0x20(%ebp),%eax
c0106329:	89 44 24 08          	mov    %eax,0x8(%esp)
c010632d:	8b 45 10             	mov    0x10(%ebp),%eax
c0106330:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106334:	8b 45 08             	mov    0x8(%ebp),%eax
c0106337:	89 04 24             	mov    %eax,(%esp)
c010633a:	e8 a6 03 00 00       	call   c01066e5 <swap_in>
c010633f:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0106342:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0106346:	74 0e                	je     c0106356 <do_pgfault+0x1a7>
                cprintf("swap_in in do_pgfault failed\n");
c0106348:	c7 04 24 cf a5 10 c0 	movl   $0xc010a5cf,(%esp)
c010634f:	e8 85 9f ff ff       	call   c01002d9 <cprintf>
c0106354:	eb 6d                	jmp    c01063c3 <do_pgfault+0x214>
                goto failed;
            }    
            page_insert(mm->pgdir, page, addr, perm);// 设置物理地址与逻辑地址的映射
c0106356:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0106359:	8b 45 08             	mov    0x8(%ebp),%eax
c010635c:	8b 40 0c             	mov    0xc(%eax),%eax
c010635f:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c0106362:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c0106366:	8b 4d 10             	mov    0x10(%ebp),%ecx
c0106369:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c010636d:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106371:	89 04 24             	mov    %eax,(%esp)
c0106374:	e8 36 dd ff ff       	call   c01040af <page_insert>
            swap_map_swappable(mm, addr, page, 1);// 设置页面可交换
c0106379:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010637c:	c7 44 24 0c 01 00 00 	movl   $0x1,0xc(%esp)
c0106383:	00 
c0106384:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106388:	8b 45 10             	mov    0x10(%ebp),%eax
c010638b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010638f:	8b 45 08             	mov    0x8(%ebp),%eax
c0106392:	89 04 24             	mov    %eax,(%esp)
c0106395:	e8 7d 01 00 00       	call   c0106517 <swap_map_swappable>
            page->pra_vaddr = addr;// 记录页面的虚拟地址
c010639a:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010639d:	8b 55 10             	mov    0x10(%ebp),%edx
c01063a0:	89 50 1c             	mov    %edx,0x1c(%eax)
c01063a3:	eb 17                	jmp    c01063bc <do_pgfault+0x20d>
        }
        else {
            cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep);
c01063a5:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01063a8:	8b 00                	mov    (%eax),%eax
c01063aa:	89 44 24 04          	mov    %eax,0x4(%esp)
c01063ae:	c7 04 24 f0 a5 10 c0 	movl   $0xc010a5f0,(%esp)
c01063b5:	e8 1f 9f ff ff       	call   c01002d9 <cprintf>
            goto failed;// 跳转到错误处理部分
c01063ba:	eb 07                	jmp    c01063c3 <do_pgfault+0x214>
        }
   }
   ret = 0;// 设置返回值为成功
c01063bc:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
failed:
    return ret;// 返回结果
c01063c3:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01063c6:	c9                   	leave  
c01063c7:	c3                   	ret    

c01063c8 <pa2page>:
pa2page(uintptr_t pa) {
c01063c8:	55                   	push   %ebp
c01063c9:	89 e5                	mov    %esp,%ebp
c01063cb:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c01063ce:	8b 45 08             	mov    0x8(%ebp),%eax
c01063d1:	c1 e8 0c             	shr    $0xc,%eax
c01063d4:	89 c2                	mov    %eax,%edx
c01063d6:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c01063db:	39 c2                	cmp    %eax,%edx
c01063dd:	72 1c                	jb     c01063fb <pa2page+0x33>
        panic("pa2page called with invalid pa");
c01063df:	c7 44 24 08 18 a6 10 	movl   $0xc010a618,0x8(%esp)
c01063e6:	c0 
c01063e7:	c7 44 24 04 5b 00 00 	movl   $0x5b,0x4(%esp)
c01063ee:	00 
c01063ef:	c7 04 24 37 a6 10 c0 	movl   $0xc010a637,(%esp)
c01063f6:	e8 4a a0 ff ff       	call   c0100445 <__panic>
    return &pages[PPN(pa)];
c01063fb:	a1 78 70 12 c0       	mov    0xc0127078,%eax
c0106400:	8b 55 08             	mov    0x8(%ebp),%edx
c0106403:	c1 ea 0c             	shr    $0xc,%edx
c0106406:	c1 e2 05             	shl    $0x5,%edx
c0106409:	01 d0                	add    %edx,%eax
}
c010640b:	c9                   	leave  
c010640c:	c3                   	ret    

c010640d <pte2page>:
pte2page(pte_t pte) {
c010640d:	55                   	push   %ebp
c010640e:	89 e5                	mov    %esp,%ebp
c0106410:	83 ec 18             	sub    $0x18,%esp
    if (!(pte & PTE_P)) {
c0106413:	8b 45 08             	mov    0x8(%ebp),%eax
c0106416:	83 e0 01             	and    $0x1,%eax
c0106419:	85 c0                	test   %eax,%eax
c010641b:	75 1c                	jne    c0106439 <pte2page+0x2c>
        panic("pte2page called with invalid pte");
c010641d:	c7 44 24 08 48 a6 10 	movl   $0xc010a648,0x8(%esp)
c0106424:	c0 
c0106425:	c7 44 24 04 6d 00 00 	movl   $0x6d,0x4(%esp)
c010642c:	00 
c010642d:	c7 04 24 37 a6 10 c0 	movl   $0xc010a637,(%esp)
c0106434:	e8 0c a0 ff ff       	call   c0100445 <__panic>
    return pa2page(PTE_ADDR(pte));
c0106439:	8b 45 08             	mov    0x8(%ebp),%eax
c010643c:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0106441:	89 04 24             	mov    %eax,(%esp)
c0106444:	e8 7f ff ff ff       	call   c01063c8 <pa2page>
}
c0106449:	c9                   	leave  
c010644a:	c3                   	ret    

c010644b <swap_init>:

static void check_swap(void);

int
swap_init(void)
{
c010644b:	f3 0f 1e fb          	endbr32 
c010644f:	55                   	push   %ebp
c0106450:	89 e5                	mov    %esp,%ebp
c0106452:	83 ec 28             	sub    $0x28,%esp
     // 初始化交换文件系统
     swapfs_init();
c0106455:	e8 18 1e 00 00       	call   c0108272 <swapfs_init>

     // 检查最大交换偏移量是否在合法范围内
     if (!(1024 <= max_swap_offset && max_swap_offset < MAX_SWAP_OFFSET_LIMIT))
c010645a:	a1 3c 71 12 c0       	mov    0xc012713c,%eax
c010645f:	3d ff 03 00 00       	cmp    $0x3ff,%eax
c0106464:	76 0c                	jbe    c0106472 <swap_init+0x27>
c0106466:	a1 3c 71 12 c0       	mov    0xc012713c,%eax
c010646b:	3d ff ff ff 00       	cmp    $0xffffff,%eax
c0106470:	76 25                	jbe    c0106497 <swap_init+0x4c>
     {    
           // 如果最大交换偏移量不合法，输出错误信息并panic
          panic("bad max_swap_offset %08x.\n", max_swap_offset);
c0106472:	a1 3c 71 12 c0       	mov    0xc012713c,%eax
c0106477:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010647b:	c7 44 24 08 69 a6 10 	movl   $0xc010a669,0x8(%esp)
c0106482:	c0 
c0106483:	c7 44 24 04 28 00 00 	movl   $0x28,0x4(%esp)
c010648a:	00 
c010648b:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106492:	e8 ae 9f ff ff       	call   c0100445 <__panic>
     }
     
     // 选择并设置交换管理器为FIFO（先进先出）策略
     sm = &swap_manager_fifo;
c0106497:	c7 05 18 70 12 c0 40 	movl   $0xc0123a40,0xc0127018
c010649e:	3a 12 c0 

     // 调用选定交换管理器的初始化函数
     int r = sm->init();
c01064a1:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c01064a6:	8b 40 04             	mov    0x4(%eax),%eax
c01064a9:	ff d0                	call   *%eax
c01064ab:	89 45 f4             	mov    %eax,-0xc(%ebp)

     // 如果交换管理器初始化成功
     if (r == 0)
c01064ae:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01064b2:	75 26                	jne    c01064da <swap_init+0x8f>
     {
          // 标记交换空间初始化为成功
          swap_init_ok = 1;
c01064b4:	c7 05 10 70 12 c0 01 	movl   $0x1,0xc0127010
c01064bb:	00 00 00 

          cprintf("SWAP: manager = %s\n", sm->name);
c01064be:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c01064c3:	8b 00                	mov    (%eax),%eax
c01064c5:	89 44 24 04          	mov    %eax,0x4(%esp)
c01064c9:	c7 04 24 93 a6 10 c0 	movl   $0xc010a693,(%esp)
c01064d0:	e8 04 9e ff ff       	call   c01002d9 <cprintf>
          // 检查交换空间状态
          check_swap();
c01064d5:	e8 b6 04 00 00       	call   c0106990 <check_swap>
     }
     // 返回初始化结果
     return r;
c01064da:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01064dd:	c9                   	leave  
c01064de:	c3                   	ret    

c01064df <swap_init_mm>:

int
swap_init_mm(struct mm_struct *mm)
{
c01064df:	f3 0f 1e fb          	endbr32 
c01064e3:	55                   	push   %ebp
c01064e4:	89 e5                	mov    %esp,%ebp
c01064e6:	83 ec 18             	sub    $0x18,%esp
     //调用 sm 结构体中的 init_mm 函数，并将 mm 作为参数传递
     return sm->init_mm(mm);
c01064e9:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c01064ee:	8b 40 08             	mov    0x8(%eax),%eax
c01064f1:	8b 55 08             	mov    0x8(%ebp),%edx
c01064f4:	89 14 24             	mov    %edx,(%esp)
c01064f7:	ff d0                	call   *%eax
}
c01064f9:	c9                   	leave  
c01064fa:	c3                   	ret    

c01064fb <swap_tick_event>:
 *
 * 返回值: sm->tick_event(mm)的返回值
 */
int
swap_tick_event(struct mm_struct *mm)
{
c01064fb:	f3 0f 1e fb          	endbr32 
c01064ff:	55                   	push   %ebp
c0106500:	89 e5                	mov    %esp,%ebp
c0106502:	83 ec 18             	sub    $0x18,%esp
     return sm->tick_event(mm);
c0106505:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c010650a:	8b 40 0c             	mov    0xc(%eax),%eax
c010650d:	8b 55 08             	mov    0x8(%ebp),%edx
c0106510:	89 14 24             	mov    %edx,(%esp)
c0106513:	ff d0                	call   *%eax
}
c0106515:	c9                   	leave  
c0106516:	c3                   	ret    

c0106517 <swap_map_swappable>:
 * 此函数的作用是作为交换操作的接口，根据swap_in参数决定是将页面交换入还是交换出
 * 它实际上调用了结构体sm中定义的map_swappable函数，因此具体的操作逻辑依赖于该函数的实现
 */
int
swap_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
{
c0106517:	f3 0f 1e fb          	endbr32 
c010651b:	55                   	push   %ebp
c010651c:	89 e5                	mov    %esp,%ebp
c010651e:	83 ec 18             	sub    $0x18,%esp
     return sm->map_swappable(mm, addr, page, swap_in);
c0106521:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c0106526:	8b 40 10             	mov    0x10(%eax),%eax
c0106529:	8b 55 14             	mov    0x14(%ebp),%edx
c010652c:	89 54 24 0c          	mov    %edx,0xc(%esp)
c0106530:	8b 55 10             	mov    0x10(%ebp),%edx
c0106533:	89 54 24 08          	mov    %edx,0x8(%esp)
c0106537:	8b 55 0c             	mov    0xc(%ebp),%edx
c010653a:	89 54 24 04          	mov    %edx,0x4(%esp)
c010653e:	8b 55 08             	mov    0x8(%ebp),%edx
c0106541:	89 14 24             	mov    %edx,(%esp)
c0106544:	ff d0                	call   *%eax
}
c0106546:	c9                   	leave  
c0106547:	c3                   	ret    

c0106548 <swap_set_unswappable>:
 * 此函数通过调用sm->set_unswappable方法来实现，其主要目的是防止指定的内存区域被交换到磁盘，
 * 通常用于那些需要常驻内存不能被交换出的特殊页面。成功时返回0，失败时返回非零值。
 */
int
swap_set_unswappable(struct mm_struct *mm, uintptr_t addr)
{
c0106548:	f3 0f 1e fb          	endbr32 
c010654c:	55                   	push   %ebp
c010654d:	89 e5                	mov    %esp,%ebp
c010654f:	83 ec 18             	sub    $0x18,%esp
     return sm->set_unswappable(mm, addr);
c0106552:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c0106557:	8b 40 14             	mov    0x14(%eax),%eax
c010655a:	8b 55 0c             	mov    0xc(%ebp),%edx
c010655d:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106561:	8b 55 08             	mov    0x8(%ebp),%edx
c0106564:	89 14 24             	mov    %edx,(%esp)
c0106567:	ff d0                	call   *%eax
}
c0106569:	c9                   	leave  
c010656a:	c3                   	ret    

c010656b <swap_out>:
 * 此函数通过选择 victim 页面并将其内容写入到交换空间中，来实现内存中页面的交换出操作。
 * 它主要用于内存压力较大时，释放内存空间，确保系统稳定运行。
 */
int
swap_out(struct mm_struct *mm, int n, int in_tick)
{
c010656b:	f3 0f 1e fb          	endbr32 
c010656f:	55                   	push   %ebp
c0106570:	89 e5                	mov    %esp,%ebp
c0106572:	83 ec 38             	sub    $0x38,%esp
     int i;
     for (i = 0; i != n; ++ i)// 循环 n 次，每次处理一个页面
c0106575:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c010657c:	e9 53 01 00 00       	jmp    c01066d4 <swap_out+0x169>
          uintptr_t v; // 用于存储页面的虚拟地址
          //struct Page **ptr_page=NULL;
          struct Page *page;  // 用于存储选中的页面
          // cprintf("i %d, SWAP: call swap_out_victim\n",i);
          // 调用 swap_out_victim 函数选择一个 victim 页面
          int r = sm->swap_out_victim(mm, &page, in_tick);
c0106581:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c0106586:	8b 40 18             	mov    0x18(%eax),%eax
c0106589:	8b 55 10             	mov    0x10(%ebp),%edx
c010658c:	89 54 24 08          	mov    %edx,0x8(%esp)
c0106590:	8d 55 e4             	lea    -0x1c(%ebp),%edx
c0106593:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106597:	8b 55 08             	mov    0x8(%ebp),%edx
c010659a:	89 14 24             	mov    %edx,(%esp)
c010659d:	ff d0                	call   *%eax
c010659f:	89 45 f0             	mov    %eax,-0x10(%ebp)
          if (r != 0) {// 如果选择失败
c01065a2:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01065a6:	74 18                	je     c01065c0 <swap_out+0x55>
                    cprintf("i %d, swap_out: call swap_out_victim failed\n",i);// 输出错误信息
c01065a8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01065ab:	89 44 24 04          	mov    %eax,0x4(%esp)
c01065af:	c7 04 24 a8 a6 10 c0 	movl   $0xc010a6a8,(%esp)
c01065b6:	e8 1e 9d ff ff       	call   c01002d9 <cprintf>
c01065bb:	e9 20 01 00 00       	jmp    c01066e0 <swap_out+0x175>
          }          
          //assert(!PageReserved(page));

          //cprintf("SWAP: choose victim page 0x%08x\n", page);
          
          v=page->pra_vaddr;  // 获取页面的虚拟地址
c01065c0:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01065c3:	8b 40 1c             	mov    0x1c(%eax),%eax
c01065c6:	89 45 ec             	mov    %eax,-0x14(%ebp)
          pte_t *ptep = get_pte(mm->pgdir, v, 0); // 获取页面表项指针
c01065c9:	8b 45 08             	mov    0x8(%ebp),%eax
c01065cc:	8b 40 0c             	mov    0xc(%eax),%eax
c01065cf:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01065d6:	00 
c01065d7:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01065da:	89 54 24 04          	mov    %edx,0x4(%esp)
c01065de:	89 04 24             	mov    %eax,(%esp)
c01065e1:	e8 84 d8 ff ff       	call   c0103e6a <get_pte>
c01065e6:	89 45 e8             	mov    %eax,-0x18(%ebp)
          assert((*ptep & PTE_P) != 0); // 断言页面在物理内存中存在
c01065e9:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01065ec:	8b 00                	mov    (%eax),%eax
c01065ee:	83 e0 01             	and    $0x1,%eax
c01065f1:	85 c0                	test   %eax,%eax
c01065f3:	75 24                	jne    c0106619 <swap_out+0xae>
c01065f5:	c7 44 24 0c d5 a6 10 	movl   $0xc010a6d5,0xc(%esp)
c01065fc:	c0 
c01065fd:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106604:	c0 
c0106605:	c7 44 24 04 9b 00 00 	movl   $0x9b,0x4(%esp)
c010660c:	00 
c010660d:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106614:	e8 2c 9e ff ff       	call   c0100445 <__panic>

          if (swapfs_write( (page->pra_vaddr/PGSIZE+1)<<8, page) != 0) {// 将页面内容写入交换文件
c0106619:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010661c:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010661f:	8b 52 1c             	mov    0x1c(%edx),%edx
c0106622:	c1 ea 0c             	shr    $0xc,%edx
c0106625:	42                   	inc    %edx
c0106626:	c1 e2 08             	shl    $0x8,%edx
c0106629:	89 44 24 04          	mov    %eax,0x4(%esp)
c010662d:	89 14 24             	mov    %edx,(%esp)
c0106630:	e8 00 1d 00 00       	call   c0108335 <swapfs_write>
c0106635:	85 c0                	test   %eax,%eax
c0106637:	74 34                	je     c010666d <swap_out+0x102>
                    cprintf("SWAP: failed to save\n");// 如果写入失败，输出错误信息
c0106639:	c7 04 24 ff a6 10 c0 	movl   $0xc010a6ff,(%esp)
c0106640:	e8 94 9c ff ff       	call   c01002d9 <cprintf>
                    sm->map_swappable(mm, v, page, 0);// 标记页面为不可交换
c0106645:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c010664a:	8b 40 10             	mov    0x10(%eax),%eax
c010664d:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0106650:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0106657:	00 
c0106658:	89 54 24 08          	mov    %edx,0x8(%esp)
c010665c:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010665f:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106663:	8b 55 08             	mov    0x8(%ebp),%edx
c0106666:	89 14 24             	mov    %edx,(%esp)
c0106669:	ff d0                	call   *%eax
c010666b:	eb 64                	jmp    c01066d1 <swap_out+0x166>
                    continue;
          }
          else {
                    cprintf("swap_out: i %d, store page in vaddr 0x%x to disk swap entry %d\n", i, v, page->pra_vaddr/PGSIZE+1);
c010666d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106670:	8b 40 1c             	mov    0x1c(%eax),%eax
c0106673:	c1 e8 0c             	shr    $0xc,%eax
c0106676:	40                   	inc    %eax
c0106677:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010667b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010667e:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106682:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106685:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106689:	c7 04 24 18 a7 10 c0 	movl   $0xc010a718,(%esp)
c0106690:	e8 44 9c ff ff       	call   c01002d9 <cprintf>
                    *ptep = (page->pra_vaddr/PGSIZE+1)<<8;  // 更新页面表项，标记页面已交换到磁盘
c0106695:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106698:	8b 40 1c             	mov    0x1c(%eax),%eax
c010669b:	c1 e8 0c             	shr    $0xc,%eax
c010669e:	40                   	inc    %eax
c010669f:	c1 e0 08             	shl    $0x8,%eax
c01066a2:	89 c2                	mov    %eax,%edx
c01066a4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01066a7:	89 10                	mov    %edx,(%eax)
                    free_page(page);    // 释放页面
c01066a9:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01066ac:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01066b3:	00 
c01066b4:	89 04 24             	mov    %eax,(%esp)
c01066b7:	e8 52 d1 ff ff       	call   c010380e <free_pages>
          }
          
          tlb_invalidate(mm->pgdir, v); // 使 TLB 中对应的条目失效
c01066bc:	8b 45 08             	mov    0x8(%ebp),%eax
c01066bf:	8b 40 0c             	mov    0xc(%eax),%eax
c01066c2:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01066c5:	89 54 24 04          	mov    %edx,0x4(%esp)
c01066c9:	89 04 24             	mov    %eax,(%esp)
c01066cc:	e8 9b da ff ff       	call   c010416c <tlb_invalidate>
     for (i = 0; i != n; ++ i)// 循环 n 次，每次处理一个页面
c01066d1:	ff 45 f4             	incl   -0xc(%ebp)
c01066d4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01066d7:	3b 45 0c             	cmp    0xc(%ebp),%eax
c01066da:	0f 85 a1 fe ff ff    	jne    c0106581 <swap_out+0x16>
     }
     return i; // 返回实际交换出的页面数量
c01066e0:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01066e3:	c9                   	leave  
c01066e4:	c3                   	ret    

c01066e5 <swap_in>:

//实现一个页交换功能。
int
swap_in(struct mm_struct *mm, uintptr_t addr, struct Page **ptr_result)
{
c01066e5:	f3 0f 1e fb          	endbr32 
c01066e9:	55                   	push   %ebp
c01066ea:	89 e5                	mov    %esp,%ebp
c01066ec:	83 ec 28             	sub    $0x28,%esp
     //分配一个新的页面result
     struct Page *result = alloc_page();
c01066ef:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01066f6:	e8 a4 d0 ff ff       	call   c010379f <alloc_pages>
c01066fb:	89 45 f4             	mov    %eax,-0xc(%ebp)
     assert(result!=NULL);
c01066fe:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0106702:	75 24                	jne    c0106728 <swap_in+0x43>
c0106704:	c7 44 24 0c 58 a7 10 	movl   $0xc010a758,0xc(%esp)
c010670b:	c0 
c010670c:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106713:	c0 
c0106714:	c7 44 24 04 b3 00 00 	movl   $0xb3,0x4(%esp)
c010671b:	00 
c010671c:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106723:	e8 1d 9d ff ff       	call   c0100445 <__panic>
     //获取虚拟地址 addr 对应的页表项指针 ptep
     pte_t *ptep = get_pte(mm->pgdir, addr, 0);
c0106728:	8b 45 08             	mov    0x8(%ebp),%eax
c010672b:	8b 40 0c             	mov    0xc(%eax),%eax
c010672e:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0106735:	00 
c0106736:	8b 55 0c             	mov    0xc(%ebp),%edx
c0106739:	89 54 24 04          	mov    %edx,0x4(%esp)
c010673d:	89 04 24             	mov    %eax,(%esp)
c0106740:	e8 25 d7 ff ff       	call   c0103e6a <get_pte>
c0106745:	89 45 f0             	mov    %eax,-0x10(%ebp)
     // cprintf("SWAP: load ptep %x swap entry %d to vaddr 0x%08x, page %x, No %d\n", ptep, (*ptep)>>8, addr, result, (result-pages));
    
     int r;
     //从交换文件中读取数据到新分配的页面 result 中
     if ((r = swapfs_read((*ptep), result)) != 0)
c0106748:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010674b:	8b 00                	mov    (%eax),%eax
c010674d:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0106750:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106754:	89 04 24             	mov    %eax,(%esp)
c0106757:	e8 63 1b 00 00       	call   c01082bf <swapfs_read>
c010675c:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010675f:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0106763:	74 2a                	je     c010678f <swap_in+0xaa>
     {
        assert(r!=0);
c0106765:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0106769:	75 24                	jne    c010678f <swap_in+0xaa>
c010676b:	c7 44 24 0c 65 a7 10 	movl   $0xc010a765,0xc(%esp)
c0106772:	c0 
c0106773:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c010677a:	c0 
c010677b:	c7 44 24 04 bc 00 00 	movl   $0xbc,0x4(%esp)
c0106782:	00 
c0106783:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c010678a:	e8 b6 9c ff ff       	call   c0100445 <__panic>
     }
     cprintf("swap_in: load disk swap entry %d with swap_page in vadr 0x%x\n", (*ptep)>>8, addr);
c010678f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106792:	8b 00                	mov    (%eax),%eax
c0106794:	c1 e8 08             	shr    $0x8,%eax
c0106797:	89 c2                	mov    %eax,%edx
c0106799:	8b 45 0c             	mov    0xc(%ebp),%eax
c010679c:	89 44 24 08          	mov    %eax,0x8(%esp)
c01067a0:	89 54 24 04          	mov    %edx,0x4(%esp)
c01067a4:	c7 04 24 6c a7 10 c0 	movl   $0xc010a76c,(%esp)
c01067ab:	e8 29 9b ff ff       	call   c01002d9 <cprintf>
     *ptr_result=result;
c01067b0:	8b 45 10             	mov    0x10(%ebp),%eax
c01067b3:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01067b6:	89 10                	mov    %edx,(%eax)
     return 0;
c01067b8:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01067bd:	c9                   	leave  
c01067be:	c3                   	ret    

c01067bf <check_content_set>:
 * 通过向特定内存地址写入数据，并检查页面故障次数是否符合预期，来验证页面管理机制的正确性。
 * 此函数没有输入参数和返回值。
 */
static inline void
check_content_set(void)
{
c01067bf:	55                   	push   %ebp
c01067c0:	89 e5                	mov    %esp,%ebp
c01067c2:	83 ec 18             	sub    $0x18,%esp
     *(unsigned char *)0x1000 = 0x0a;
c01067c5:	b8 00 10 00 00       	mov    $0x1000,%eax
c01067ca:	c6 00 0a             	movb   $0xa,(%eax)
     assert(pgfault_num==1);
c01067cd:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01067d2:	83 f8 01             	cmp    $0x1,%eax
c01067d5:	74 24                	je     c01067fb <check_content_set+0x3c>
c01067d7:	c7 44 24 0c aa a7 10 	movl   $0xc010a7aa,0xc(%esp)
c01067de:	c0 
c01067df:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c01067e6:	c0 
c01067e7:	c7 44 24 04 cd 00 00 	movl   $0xcd,0x4(%esp)
c01067ee:	00 
c01067ef:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c01067f6:	e8 4a 9c ff ff       	call   c0100445 <__panic>
     *(unsigned char *)0x1010 = 0x0a;
c01067fb:	b8 10 10 00 00       	mov    $0x1010,%eax
c0106800:	c6 00 0a             	movb   $0xa,(%eax)
     assert(pgfault_num==1);
c0106803:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c0106808:	83 f8 01             	cmp    $0x1,%eax
c010680b:	74 24                	je     c0106831 <check_content_set+0x72>
c010680d:	c7 44 24 0c aa a7 10 	movl   $0xc010a7aa,0xc(%esp)
c0106814:	c0 
c0106815:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c010681c:	c0 
c010681d:	c7 44 24 04 cf 00 00 	movl   $0xcf,0x4(%esp)
c0106824:	00 
c0106825:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c010682c:	e8 14 9c ff ff       	call   c0100445 <__panic>
     *(unsigned char *)0x2000 = 0x0b;
c0106831:	b8 00 20 00 00       	mov    $0x2000,%eax
c0106836:	c6 00 0b             	movb   $0xb,(%eax)
     assert(pgfault_num==2);
c0106839:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c010683e:	83 f8 02             	cmp    $0x2,%eax
c0106841:	74 24                	je     c0106867 <check_content_set+0xa8>
c0106843:	c7 44 24 0c b9 a7 10 	movl   $0xc010a7b9,0xc(%esp)
c010684a:	c0 
c010684b:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106852:	c0 
c0106853:	c7 44 24 04 d1 00 00 	movl   $0xd1,0x4(%esp)
c010685a:	00 
c010685b:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106862:	e8 de 9b ff ff       	call   c0100445 <__panic>
     *(unsigned char *)0x2010 = 0x0b;
c0106867:	b8 10 20 00 00       	mov    $0x2010,%eax
c010686c:	c6 00 0b             	movb   $0xb,(%eax)
     assert(pgfault_num==2);
c010686f:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c0106874:	83 f8 02             	cmp    $0x2,%eax
c0106877:	74 24                	je     c010689d <check_content_set+0xde>
c0106879:	c7 44 24 0c b9 a7 10 	movl   $0xc010a7b9,0xc(%esp)
c0106880:	c0 
c0106881:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106888:	c0 
c0106889:	c7 44 24 04 d3 00 00 	movl   $0xd3,0x4(%esp)
c0106890:	00 
c0106891:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106898:	e8 a8 9b ff ff       	call   c0100445 <__panic>
     *(unsigned char *)0x3000 = 0x0c;
c010689d:	b8 00 30 00 00       	mov    $0x3000,%eax
c01068a2:	c6 00 0c             	movb   $0xc,(%eax)
     assert(pgfault_num==3);
c01068a5:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01068aa:	83 f8 03             	cmp    $0x3,%eax
c01068ad:	74 24                	je     c01068d3 <check_content_set+0x114>
c01068af:	c7 44 24 0c c8 a7 10 	movl   $0xc010a7c8,0xc(%esp)
c01068b6:	c0 
c01068b7:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c01068be:	c0 
c01068bf:	c7 44 24 04 d5 00 00 	movl   $0xd5,0x4(%esp)
c01068c6:	00 
c01068c7:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c01068ce:	e8 72 9b ff ff       	call   c0100445 <__panic>
     *(unsigned char *)0x3010 = 0x0c;
c01068d3:	b8 10 30 00 00       	mov    $0x3010,%eax
c01068d8:	c6 00 0c             	movb   $0xc,(%eax)
     assert(pgfault_num==3);
c01068db:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c01068e0:	83 f8 03             	cmp    $0x3,%eax
c01068e3:	74 24                	je     c0106909 <check_content_set+0x14a>
c01068e5:	c7 44 24 0c c8 a7 10 	movl   $0xc010a7c8,0xc(%esp)
c01068ec:	c0 
c01068ed:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c01068f4:	c0 
c01068f5:	c7 44 24 04 d7 00 00 	movl   $0xd7,0x4(%esp)
c01068fc:	00 
c01068fd:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106904:	e8 3c 9b ff ff       	call   c0100445 <__panic>
     *(unsigned char *)0x4000 = 0x0d;
c0106909:	b8 00 40 00 00       	mov    $0x4000,%eax
c010690e:	c6 00 0d             	movb   $0xd,(%eax)
     assert(pgfault_num==4);
c0106911:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c0106916:	83 f8 04             	cmp    $0x4,%eax
c0106919:	74 24                	je     c010693f <check_content_set+0x180>
c010691b:	c7 44 24 0c d7 a7 10 	movl   $0xc010a7d7,0xc(%esp)
c0106922:	c0 
c0106923:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c010692a:	c0 
c010692b:	c7 44 24 04 d9 00 00 	movl   $0xd9,0x4(%esp)
c0106932:	00 
c0106933:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c010693a:	e8 06 9b ff ff       	call   c0100445 <__panic>
     *(unsigned char *)0x4010 = 0x0d;
c010693f:	b8 10 40 00 00       	mov    $0x4010,%eax
c0106944:	c6 00 0d             	movb   $0xd,(%eax)
     assert(pgfault_num==4);
c0106947:	a1 0c 70 12 c0       	mov    0xc012700c,%eax
c010694c:	83 f8 04             	cmp    $0x4,%eax
c010694f:	74 24                	je     c0106975 <check_content_set+0x1b6>
c0106951:	c7 44 24 0c d7 a7 10 	movl   $0xc010a7d7,0xc(%esp)
c0106958:	c0 
c0106959:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106960:	c0 
c0106961:	c7 44 24 04 db 00 00 	movl   $0xdb,0x4(%esp)
c0106968:	00 
c0106969:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106970:	e8 d0 9a ff ff       	call   c0100445 <__panic>
}
c0106975:	90                   	nop
c0106976:	c9                   	leave  
c0106977:	c3                   	ret    

c0106978 <check_content_access>:
 * 
 * @return int 返回权限检查的结果，非零表示成功，零表示失败
 */
static inline int
check_content_access(void)
{
c0106978:	55                   	push   %ebp
c0106979:	89 e5                	mov    %esp,%ebp
c010697b:	83 ec 18             	sub    $0x18,%esp
    // 调用swap管理器的检查方法，并将结果返回
    int ret = sm->check_swap();
c010697e:	a1 18 70 12 c0       	mov    0xc0127018,%eax
c0106983:	8b 40 1c             	mov    0x1c(%eax),%eax
c0106986:	ff d0                	call   *%eax
c0106988:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return ret;
c010698b:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010698e:	c9                   	leave  
c010698f:	c3                   	ret    

c0106990 <check_swap>:
#define nr_free (free_area.nr_free)

// 检查交换机制的正确性，通过模拟页面替换算法
static void
check_swap(void)
{
c0106990:	f3 0f 1e fb          	endbr32 
c0106994:	55                   	push   %ebp
c0106995:	89 e5                	mov    %esp,%ebp
c0106997:	83 ec 78             	sub    $0x78,%esp
    //backup mem env// 备份内存环境，确保检查后没有页面丢失
     int ret, count = 0, total = 0, i;
c010699a:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c01069a1:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
     list_entry_t *le = &free_list;
c01069a8:	c7 45 e8 64 71 12 c0 	movl   $0xc0127164,-0x18(%ebp)
     while ((le = list_next(le)) != &free_list) {
c01069af:	eb 6a                	jmp    c0106a1b <check_swap+0x8b>
        struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构
c01069b1:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01069b4:	83 e8 0c             	sub    $0xc,%eax
c01069b7:	89 45 c8             	mov    %eax,-0x38(%ebp)
        assert(PageProperty(p));// 断言页面属性有效
c01069ba:	8b 45 c8             	mov    -0x38(%ebp),%eax
c01069bd:	83 c0 04             	add    $0x4,%eax
c01069c0:	c7 45 c4 01 00 00 00 	movl   $0x1,-0x3c(%ebp)
c01069c7:	89 45 c0             	mov    %eax,-0x40(%ebp)
 * @addr:   the address to count from
 * */
static inline bool
test_bit(int nr, volatile void *addr) {
    int oldbit;
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01069ca:	8b 45 c0             	mov    -0x40(%ebp),%eax
c01069cd:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c01069d0:	0f a3 10             	bt     %edx,(%eax)
c01069d3:	19 c0                	sbb    %eax,%eax
c01069d5:	89 45 bc             	mov    %eax,-0x44(%ebp)
    return oldbit != 0;
c01069d8:	83 7d bc 00          	cmpl   $0x0,-0x44(%ebp)
c01069dc:	0f 95 c0             	setne  %al
c01069df:	0f b6 c0             	movzbl %al,%eax
c01069e2:	85 c0                	test   %eax,%eax
c01069e4:	75 24                	jne    c0106a0a <check_swap+0x7a>
c01069e6:	c7 44 24 0c e6 a7 10 	movl   $0xc010a7e6,0xc(%esp)
c01069ed:	c0 
c01069ee:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c01069f5:	c0 
c01069f6:	c7 44 24 04 00 01 00 	movl   $0x100,0x4(%esp)
c01069fd:	00 
c01069fe:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106a05:	e8 3b 9a ff ff       	call   c0100445 <__panic>
        count ++, total += p->property;// 统计页面数量和属性总和
c0106a0a:	ff 45 f4             	incl   -0xc(%ebp)
c0106a0d:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0106a10:	8b 50 08             	mov    0x8(%eax),%edx
c0106a13:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106a16:	01 d0                	add    %edx,%eax
c0106a18:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0106a1b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106a1e:	89 45 b8             	mov    %eax,-0x48(%ebp)
c0106a21:	8b 45 b8             	mov    -0x48(%ebp),%eax
c0106a24:	8b 40 04             	mov    0x4(%eax),%eax
     while ((le = list_next(le)) != &free_list) {
c0106a27:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0106a2a:	81 7d e8 64 71 12 c0 	cmpl   $0xc0127164,-0x18(%ebp)
c0106a31:	0f 85 7a ff ff ff    	jne    c01069b1 <check_swap+0x21>
     }
     assert(total == nr_free_pages());// 断言统计的属性总和与空闲页面数一致
c0106a37:	e8 09 ce ff ff       	call   c0103845 <nr_free_pages>
c0106a3c:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0106a3f:	39 d0                	cmp    %edx,%eax
c0106a41:	74 24                	je     c0106a67 <check_swap+0xd7>
c0106a43:	c7 44 24 0c f6 a7 10 	movl   $0xc010a7f6,0xc(%esp)
c0106a4a:	c0 
c0106a4b:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106a52:	c0 
c0106a53:	c7 44 24 04 03 01 00 	movl   $0x103,0x4(%esp)
c0106a5a:	00 
c0106a5b:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106a62:	e8 de 99 ff ff       	call   c0100445 <__panic>
     cprintf("BEGIN check_swap: count %d, total %d\n",count,total);// 打印初始状态
c0106a67:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106a6a:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106a6e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106a71:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106a75:	c7 04 24 10 a8 10 c0 	movl   $0xc010a810,(%esp)
c0106a7c:	e8 58 98 ff ff       	call   c01002d9 <cprintf>
     
     //now we set the phy pages env // 设置物理页面环境    
     struct mm_struct *mm = mm_create();// 创建内存管理结构
c0106a81:	e8 de eb ff ff       	call   c0105664 <mm_create>
c0106a86:	89 45 e4             	mov    %eax,-0x1c(%ebp)
     assert(mm != NULL); // 断言内存管理结构创建成功
c0106a89:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0106a8d:	75 24                	jne    c0106ab3 <check_swap+0x123>
c0106a8f:	c7 44 24 0c 36 a8 10 	movl   $0xc010a836,0xc(%esp)
c0106a96:	c0 
c0106a97:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106a9e:	c0 
c0106a9f:	c7 44 24 04 08 01 00 	movl   $0x108,0x4(%esp)
c0106aa6:	00 
c0106aa7:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106aae:	e8 92 99 ff ff       	call   c0100445 <__panic>

     extern struct mm_struct *check_mm_struct;// 声明外部变量
     assert(check_mm_struct == NULL);// 断言外部变量为空
c0106ab3:	a1 84 70 12 c0       	mov    0xc0127084,%eax
c0106ab8:	85 c0                	test   %eax,%eax
c0106aba:	74 24                	je     c0106ae0 <check_swap+0x150>
c0106abc:	c7 44 24 0c 41 a8 10 	movl   $0xc010a841,0xc(%esp)
c0106ac3:	c0 
c0106ac4:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106acb:	c0 
c0106acc:	c7 44 24 04 0b 01 00 	movl   $0x10b,0x4(%esp)
c0106ad3:	00 
c0106ad4:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106adb:	e8 65 99 ff ff       	call   c0100445 <__panic>

     // 将新创建的内存管理结构赋值给外部变量
     check_mm_struct = mm;
c0106ae0:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106ae3:	a3 84 70 12 c0       	mov    %eax,0xc0127084

     pde_t *pgdir = mm->pgdir = boot_pgdir;// 设置页目录
c0106ae8:	8b 15 e0 39 12 c0    	mov    0xc01239e0,%edx
c0106aee:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106af1:	89 50 0c             	mov    %edx,0xc(%eax)
c0106af4:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106af7:	8b 40 0c             	mov    0xc(%eax),%eax
c0106afa:	89 45 e0             	mov    %eax,-0x20(%ebp)
     assert(pgdir[0] == 0);// 断言页目录的第一个条目为空
c0106afd:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0106b00:	8b 00                	mov    (%eax),%eax
c0106b02:	85 c0                	test   %eax,%eax
c0106b04:	74 24                	je     c0106b2a <check_swap+0x19a>
c0106b06:	c7 44 24 0c 59 a8 10 	movl   $0xc010a859,0xc(%esp)
c0106b0d:	c0 
c0106b0e:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106b15:	c0 
c0106b16:	c7 44 24 04 11 01 00 	movl   $0x111,0x4(%esp)
c0106b1d:	00 
c0106b1e:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106b25:	e8 1b 99 ff ff       	call   c0100445 <__panic>

     // 创建虚拟内存区域
     struct vma_struct *vma = vma_create(BEING_CHECK_VALID_VADDR, CHECK_VALID_VADDR, VM_WRITE | VM_READ);
c0106b2a:	c7 44 24 08 03 00 00 	movl   $0x3,0x8(%esp)
c0106b31:	00 
c0106b32:	c7 44 24 04 00 60 00 	movl   $0x6000,0x4(%esp)
c0106b39:	00 
c0106b3a:	c7 04 24 00 10 00 00 	movl   $0x1000,(%esp)
c0106b41:	e8 9b eb ff ff       	call   c01056e1 <vma_create>
c0106b46:	89 45 dc             	mov    %eax,-0x24(%ebp)
     assert(vma != NULL);// 断言虚拟内存区域创建成功
c0106b49:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0106b4d:	75 24                	jne    c0106b73 <check_swap+0x1e3>
c0106b4f:	c7 44 24 0c 67 a8 10 	movl   $0xc010a867,0xc(%esp)
c0106b56:	c0 
c0106b57:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106b5e:	c0 
c0106b5f:	c7 44 24 04 15 01 00 	movl   $0x115,0x4(%esp)
c0106b66:	00 
c0106b67:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106b6e:	e8 d2 98 ff ff       	call   c0100445 <__panic>

     // 插入虚拟内存区域到内存管理结构
     insert_vma_struct(mm, vma);
c0106b73:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0106b76:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106b7a:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106b7d:	89 04 24             	mov    %eax,(%esp)
c0106b80:	e8 f5 ec ff ff       	call   c010587a <insert_vma_struct>

     //setup the temp Page Table vaddr 0~4MB/ 设置临时页表，用于虚拟地址 0~4MB
     cprintf("setup Page Table for vaddr 0X1000, so alloc a page\n");// 打印设置页表的信息
c0106b85:	c7 04 24 74 a8 10 c0 	movl   $0xc010a874,(%esp)
c0106b8c:	e8 48 97 ff ff       	call   c01002d9 <cprintf>
     pte_t *temp_ptep=NULL;
c0106b91:	c7 45 d8 00 00 00 00 	movl   $0x0,-0x28(%ebp)
     temp_ptep = get_pte(mm->pgdir, BEING_CHECK_VALID_VADDR, 1);// 获取页表项
c0106b98:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106b9b:	8b 40 0c             	mov    0xc(%eax),%eax
c0106b9e:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c0106ba5:	00 
c0106ba6:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0106bad:	00 
c0106bae:	89 04 24             	mov    %eax,(%esp)
c0106bb1:	e8 b4 d2 ff ff       	call   c0103e6a <get_pte>
c0106bb6:	89 45 d8             	mov    %eax,-0x28(%ebp)
     assert(temp_ptep!= NULL);// 断言获取页表项成功
c0106bb9:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c0106bbd:	75 24                	jne    c0106be3 <check_swap+0x253>
c0106bbf:	c7 44 24 0c a8 a8 10 	movl   $0xc010a8a8,0xc(%esp)
c0106bc6:	c0 
c0106bc7:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106bce:	c0 
c0106bcf:	c7 44 24 04 1e 01 00 	movl   $0x11e,0x4(%esp)
c0106bd6:	00 
c0106bd7:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106bde:	e8 62 98 ff ff       	call   c0100445 <__panic>
     cprintf("setup Page Table vaddr 0~4MB OVER!\n");// 打印设置页表完成的信息
c0106be3:	c7 04 24 bc a8 10 c0 	movl   $0xc010a8bc,(%esp)
c0106bea:	e8 ea 96 ff ff       	call   c01002d9 <cprintf>
     
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106bef:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0106bf6:	e9 a2 00 00 00       	jmp    c0106c9d <check_swap+0x30d>
          check_rp[i] = alloc_page();// 分配页面
c0106bfb:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0106c02:	e8 98 cb ff ff       	call   c010379f <alloc_pages>
c0106c07:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0106c0a:	89 04 95 a0 70 12 c0 	mov    %eax,-0x3fed8f60(,%edx,4)
          assert(check_rp[i] != NULL );// 断言分配页面成功
c0106c11:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106c14:	8b 04 85 a0 70 12 c0 	mov    -0x3fed8f60(,%eax,4),%eax
c0106c1b:	85 c0                	test   %eax,%eax
c0106c1d:	75 24                	jne    c0106c43 <check_swap+0x2b3>
c0106c1f:	c7 44 24 0c e0 a8 10 	movl   $0xc010a8e0,0xc(%esp)
c0106c26:	c0 
c0106c27:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106c2e:	c0 
c0106c2f:	c7 44 24 04 23 01 00 	movl   $0x123,0x4(%esp)
c0106c36:	00 
c0106c37:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106c3e:	e8 02 98 ff ff       	call   c0100445 <__panic>
          assert(!PageProperty(check_rp[i]));// 断言页面属性无效
c0106c43:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106c46:	8b 04 85 a0 70 12 c0 	mov    -0x3fed8f60(,%eax,4),%eax
c0106c4d:	83 c0 04             	add    $0x4,%eax
c0106c50:	c7 45 b4 01 00 00 00 	movl   $0x1,-0x4c(%ebp)
c0106c57:	89 45 b0             	mov    %eax,-0x50(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0106c5a:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0106c5d:	8b 55 b4             	mov    -0x4c(%ebp),%edx
c0106c60:	0f a3 10             	bt     %edx,(%eax)
c0106c63:	19 c0                	sbb    %eax,%eax
c0106c65:	89 45 ac             	mov    %eax,-0x54(%ebp)
    return oldbit != 0;
c0106c68:	83 7d ac 00          	cmpl   $0x0,-0x54(%ebp)
c0106c6c:	0f 95 c0             	setne  %al
c0106c6f:	0f b6 c0             	movzbl %al,%eax
c0106c72:	85 c0                	test   %eax,%eax
c0106c74:	74 24                	je     c0106c9a <check_swap+0x30a>
c0106c76:	c7 44 24 0c f4 a8 10 	movl   $0xc010a8f4,0xc(%esp)
c0106c7d:	c0 
c0106c7e:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106c85:	c0 
c0106c86:	c7 44 24 04 24 01 00 	movl   $0x124,0x4(%esp)
c0106c8d:	00 
c0106c8e:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106c95:	e8 ab 97 ff ff       	call   c0100445 <__panic>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106c9a:	ff 45 ec             	incl   -0x14(%ebp)
c0106c9d:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c0106ca1:	0f 8e 54 ff ff ff    	jle    c0106bfb <check_swap+0x26b>
     }
     list_entry_t free_list_store = free_list;// 保存当前空闲列表
c0106ca7:	a1 64 71 12 c0       	mov    0xc0127164,%eax
c0106cac:	8b 15 68 71 12 c0    	mov    0xc0127168,%edx
c0106cb2:	89 45 98             	mov    %eax,-0x68(%ebp)
c0106cb5:	89 55 9c             	mov    %edx,-0x64(%ebp)
c0106cb8:	c7 45 a4 64 71 12 c0 	movl   $0xc0127164,-0x5c(%ebp)
    elm->prev = elm->next = elm;
c0106cbf:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c0106cc2:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c0106cc5:	89 50 04             	mov    %edx,0x4(%eax)
c0106cc8:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c0106ccb:	8b 50 04             	mov    0x4(%eax),%edx
c0106cce:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c0106cd1:	89 10                	mov    %edx,(%eax)
}
c0106cd3:	90                   	nop
c0106cd4:	c7 45 a8 64 71 12 c0 	movl   $0xc0127164,-0x58(%ebp)
    return list->next == list;
c0106cdb:	8b 45 a8             	mov    -0x58(%ebp),%eax
c0106cde:	8b 40 04             	mov    0x4(%eax),%eax
c0106ce1:	39 45 a8             	cmp    %eax,-0x58(%ebp)
c0106ce4:	0f 94 c0             	sete   %al
c0106ce7:	0f b6 c0             	movzbl %al,%eax
     list_init(&free_list);// 初始化空闲列表
     assert(list_empty(&free_list));// 断言空闲列表为空
c0106cea:	85 c0                	test   %eax,%eax
c0106cec:	75 24                	jne    c0106d12 <check_swap+0x382>
c0106cee:	c7 44 24 0c 0f a9 10 	movl   $0xc010a90f,0xc(%esp)
c0106cf5:	c0 
c0106cf6:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106cfd:	c0 
c0106cfe:	c7 44 24 04 28 01 00 	movl   $0x128,0x4(%esp)
c0106d05:	00 
c0106d06:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106d0d:	e8 33 97 ff ff       	call   c0100445 <__panic>
     
     //assert(alloc_page() == NULL);
     
     unsigned int nr_free_store = nr_free;// 保存当前空闲页面数
c0106d12:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c0106d17:	89 45 d4             	mov    %eax,-0x2c(%ebp)
     nr_free = 0;// 将空闲页面数设为 0
c0106d1a:	c7 05 6c 71 12 c0 00 	movl   $0x0,0xc012716c
c0106d21:	00 00 00 
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106d24:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0106d2b:	eb 1d                	jmp    c0106d4a <check_swap+0x3ba>
        free_pages(check_rp[i],1);// 释放页面
c0106d2d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106d30:	8b 04 85 a0 70 12 c0 	mov    -0x3fed8f60(,%eax,4),%eax
c0106d37:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0106d3e:	00 
c0106d3f:	89 04 24             	mov    %eax,(%esp)
c0106d42:	e8 c7 ca ff ff       	call   c010380e <free_pages>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106d47:	ff 45 ec             	incl   -0x14(%ebp)
c0106d4a:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c0106d4e:	7e dd                	jle    c0106d2d <check_swap+0x39d>
     }
     assert(nr_free==CHECK_VALID_PHY_PAGE_NUM);// 断言释放的页面数正确
c0106d50:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c0106d55:	83 f8 04             	cmp    $0x4,%eax
c0106d58:	74 24                	je     c0106d7e <check_swap+0x3ee>
c0106d5a:	c7 44 24 0c 28 a9 10 	movl   $0xc010a928,0xc(%esp)
c0106d61:	c0 
c0106d62:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106d69:	c0 
c0106d6a:	c7 44 24 04 31 01 00 	movl   $0x131,0x4(%esp)
c0106d71:	00 
c0106d72:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106d79:	e8 c7 96 ff ff       	call   c0100445 <__panic>
     
     cprintf("set up init env for check_swap begin!\n");// 打印设置初始环境开始的信息
c0106d7e:	c7 04 24 4c a9 10 c0 	movl   $0xc010a94c,(%esp)
c0106d85:	e8 4f 95 ff ff       	call   c01002d9 <cprintf>
     //setup initial vir_page<->phy_page environment for page relpacement algorithm 
     // 设置初始虚拟到物理页面环境，用于页面替换算法
     
     pgfault_num=0;// 初始化页面故障数
c0106d8a:	c7 05 0c 70 12 c0 00 	movl   $0x0,0xc012700c
c0106d91:	00 00 00 
     
     check_content_set();// 设置检查内容
c0106d94:	e8 26 fa ff ff       	call   c01067bf <check_content_set>
     assert( nr_free == 0);  // 断言空闲页面数为 0       
c0106d99:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c0106d9e:	85 c0                	test   %eax,%eax
c0106da0:	74 24                	je     c0106dc6 <check_swap+0x436>
c0106da2:	c7 44 24 0c 73 a9 10 	movl   $0xc010a973,0xc(%esp)
c0106da9:	c0 
c0106daa:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106db1:	c0 
c0106db2:	c7 44 24 04 3a 01 00 	movl   $0x13a,0x4(%esp)
c0106db9:	00 
c0106dba:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106dc1:	e8 7f 96 ff ff       	call   c0100445 <__panic>
     for(i = 0; i<MAX_SEQ_NO ; i++) 
c0106dc6:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0106dcd:	eb 25                	jmp    c0106df4 <check_swap+0x464>
         swap_out_seq_no[i]=swap_in_seq_no[i]=-1;// 初始化页面替换序列号
c0106dcf:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106dd2:	c7 04 85 c0 70 12 c0 	movl   $0xffffffff,-0x3fed8f40(,%eax,4)
c0106dd9:	ff ff ff ff 
c0106ddd:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106de0:	8b 14 85 c0 70 12 c0 	mov    -0x3fed8f40(,%eax,4),%edx
c0106de7:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106dea:	89 14 85 00 71 12 c0 	mov    %edx,-0x3fed8f00(,%eax,4)
     for(i = 0; i<MAX_SEQ_NO ; i++) 
c0106df1:	ff 45 ec             	incl   -0x14(%ebp)
c0106df4:	83 7d ec 09          	cmpl   $0x9,-0x14(%ebp)
c0106df8:	7e d5                	jle    c0106dcf <check_swap+0x43f>
     
     for (i= 0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106dfa:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0106e01:	e9 e8 00 00 00       	jmp    c0106eee <check_swap+0x55e>
         check_ptep[i]=0;
c0106e06:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106e09:	c7 04 85 54 71 12 c0 	movl   $0x0,-0x3fed8eac(,%eax,4)
c0106e10:	00 00 00 00 
         check_ptep[i] = get_pte(pgdir, (i+1)*0x1000, 0);// 获取页表项
c0106e14:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106e17:	40                   	inc    %eax
c0106e18:	c1 e0 0c             	shl    $0xc,%eax
c0106e1b:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0106e22:	00 
c0106e23:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106e27:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0106e2a:	89 04 24             	mov    %eax,(%esp)
c0106e2d:	e8 38 d0 ff ff       	call   c0103e6a <get_pte>
c0106e32:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0106e35:	89 04 95 54 71 12 c0 	mov    %eax,-0x3fed8eac(,%edx,4)
         //cprintf("i %d, check_ptep addr %x, value %x\n", i, check_ptep[i], *check_ptep[i]);
         assert(check_ptep[i] != NULL);// 断言获取页表项成功
c0106e3c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106e3f:	8b 04 85 54 71 12 c0 	mov    -0x3fed8eac(,%eax,4),%eax
c0106e46:	85 c0                	test   %eax,%eax
c0106e48:	75 24                	jne    c0106e6e <check_swap+0x4de>
c0106e4a:	c7 44 24 0c 80 a9 10 	movl   $0xc010a980,0xc(%esp)
c0106e51:	c0 
c0106e52:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106e59:	c0 
c0106e5a:	c7 44 24 04 42 01 00 	movl   $0x142,0x4(%esp)
c0106e61:	00 
c0106e62:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106e69:	e8 d7 95 ff ff       	call   c0100445 <__panic>
         assert(pte2page(*check_ptep[i]) == check_rp[i]); // 断言页表项对应的页面正确
c0106e6e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106e71:	8b 04 85 54 71 12 c0 	mov    -0x3fed8eac(,%eax,4),%eax
c0106e78:	8b 00                	mov    (%eax),%eax
c0106e7a:	89 04 24             	mov    %eax,(%esp)
c0106e7d:	e8 8b f5 ff ff       	call   c010640d <pte2page>
c0106e82:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0106e85:	8b 14 95 a0 70 12 c0 	mov    -0x3fed8f60(,%edx,4),%edx
c0106e8c:	39 d0                	cmp    %edx,%eax
c0106e8e:	74 24                	je     c0106eb4 <check_swap+0x524>
c0106e90:	c7 44 24 0c 98 a9 10 	movl   $0xc010a998,0xc(%esp)
c0106e97:	c0 
c0106e98:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106e9f:	c0 
c0106ea0:	c7 44 24 04 43 01 00 	movl   $0x143,0x4(%esp)
c0106ea7:	00 
c0106ea8:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106eaf:	e8 91 95 ff ff       	call   c0100445 <__panic>
         assert((*check_ptep[i] & PTE_P));  // 断言页表项有效        
c0106eb4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106eb7:	8b 04 85 54 71 12 c0 	mov    -0x3fed8eac(,%eax,4),%eax
c0106ebe:	8b 00                	mov    (%eax),%eax
c0106ec0:	83 e0 01             	and    $0x1,%eax
c0106ec3:	85 c0                	test   %eax,%eax
c0106ec5:	75 24                	jne    c0106eeb <check_swap+0x55b>
c0106ec7:	c7 44 24 0c c0 a9 10 	movl   $0xc010a9c0,0xc(%esp)
c0106ece:	c0 
c0106ecf:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106ed6:	c0 
c0106ed7:	c7 44 24 04 44 01 00 	movl   $0x144,0x4(%esp)
c0106ede:	00 
c0106edf:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106ee6:	e8 5a 95 ff ff       	call   c0100445 <__panic>
     for (i= 0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106eeb:	ff 45 ec             	incl   -0x14(%ebp)
c0106eee:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c0106ef2:	0f 8e 0e ff ff ff    	jle    c0106e06 <check_swap+0x476>
     }
     cprintf("set up init env for check_swap over!\n");// 打印设置初始环境完成的信息
c0106ef8:	c7 04 24 dc a9 10 c0 	movl   $0xc010a9dc,(%esp)
c0106eff:	e8 d5 93 ff ff       	call   c01002d9 <cprintf>
     // now access the virt pages to test  page relpacement algorithm 
     ret=check_content_access();
c0106f04:	e8 6f fa ff ff       	call   c0106978 <check_content_access>
c0106f09:	89 45 d0             	mov    %eax,-0x30(%ebp)
     assert(ret==0); // 断言访问检查成功
c0106f0c:	83 7d d0 00          	cmpl   $0x0,-0x30(%ebp)
c0106f10:	74 24                	je     c0106f36 <check_swap+0x5a6>
c0106f12:	c7 44 24 0c 02 aa 10 	movl   $0xc010aa02,0xc(%esp)
c0106f19:	c0 
c0106f1a:	c7 44 24 08 ea a6 10 	movl   $0xc010a6ea,0x8(%esp)
c0106f21:	c0 
c0106f22:	c7 44 24 04 49 01 00 	movl   $0x149,0x4(%esp)
c0106f29:	00 
c0106f2a:	c7 04 24 84 a6 10 c0 	movl   $0xc010a684,(%esp)
c0106f31:	e8 0f 95 ff ff       	call   c0100445 <__panic>
     
     //restore kernel mem env
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106f36:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0106f3d:	eb 1d                	jmp    c0106f5c <check_swap+0x5cc>
         free_pages(check_rp[i],1);
c0106f3f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106f42:	8b 04 85 a0 70 12 c0 	mov    -0x3fed8f60(,%eax,4),%eax
c0106f49:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0106f50:	00 
c0106f51:	89 04 24             	mov    %eax,(%esp)
c0106f54:	e8 b5 c8 ff ff       	call   c010380e <free_pages>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106f59:	ff 45 ec             	incl   -0x14(%ebp)
c0106f5c:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c0106f60:	7e dd                	jle    c0106f3f <check_swap+0x5af>
     } 

     //free_page(pte2page(*temp_ptep));
     
     mm_destroy(mm);// 销毁内存管理结构
c0106f62:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106f65:	89 04 24             	mov    %eax,(%esp)
c0106f68:	e8 45 ea ff ff       	call   c01059b2 <mm_destroy>
         
     nr_free = nr_free_store;// 恢复空闲页面数
c0106f6d:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0106f70:	a3 6c 71 12 c0       	mov    %eax,0xc012716c
     free_list = free_list_store;// 恢复空闲列表
c0106f75:	8b 45 98             	mov    -0x68(%ebp),%eax
c0106f78:	8b 55 9c             	mov    -0x64(%ebp),%edx
c0106f7b:	a3 64 71 12 c0       	mov    %eax,0xc0127164
c0106f80:	89 15 68 71 12 c0    	mov    %edx,0xc0127168

     
     le = &free_list;
c0106f86:	c7 45 e8 64 71 12 c0 	movl   $0xc0127164,-0x18(%ebp)
     while ((le = list_next(le)) != &free_list) {
c0106f8d:	eb 1c                	jmp    c0106fab <check_swap+0x61b>
         struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构
c0106f8f:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106f92:	83 e8 0c             	sub    $0xc,%eax
c0106f95:	89 45 cc             	mov    %eax,-0x34(%ebp)
         count --, total -= p->property;// 更新页面数量和属性总和
c0106f98:	ff 4d f4             	decl   -0xc(%ebp)
c0106f9b:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0106f9e:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0106fa1:	8b 40 08             	mov    0x8(%eax),%eax
c0106fa4:	29 c2                	sub    %eax,%edx
c0106fa6:	89 d0                	mov    %edx,%eax
c0106fa8:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0106fab:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106fae:	89 45 a0             	mov    %eax,-0x60(%ebp)
    return listelm->next;
c0106fb1:	8b 45 a0             	mov    -0x60(%ebp),%eax
c0106fb4:	8b 40 04             	mov    0x4(%eax),%eax
     while ((le = list_next(le)) != &free_list) {
c0106fb7:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0106fba:	81 7d e8 64 71 12 c0 	cmpl   $0xc0127164,-0x18(%ebp)
c0106fc1:	75 cc                	jne    c0106f8f <check_swap+0x5ff>
     }
     cprintf("count is %d, total is %d\n",count,total);// 打印恢复后的状态
c0106fc3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106fc6:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106fca:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106fcd:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106fd1:	c7 04 24 09 aa 10 c0 	movl   $0xc010aa09,(%esp)
c0106fd8:	e8 fc 92 ff ff       	call   c01002d9 <cprintf>
     //assert(count == 0);
     
     cprintf("check_swap() succeeded!\n");// 打印检查成功的信息
c0106fdd:	c7 04 24 23 aa 10 c0 	movl   $0xc010aa23,(%esp)
c0106fe4:	e8 f0 92 ff ff       	call   c01002d9 <cprintf>
}
c0106fe9:	90                   	nop
c0106fea:	c9                   	leave  
c0106feb:	c3                   	ret    

c0106fec <page2ppn>:
page2ppn(struct Page *page) {
c0106fec:	55                   	push   %ebp
c0106fed:	89 e5                	mov    %esp,%ebp
    return page - pages;
c0106fef:	a1 78 70 12 c0       	mov    0xc0127078,%eax
c0106ff4:	8b 55 08             	mov    0x8(%ebp),%edx
c0106ff7:	29 c2                	sub    %eax,%edx
c0106ff9:	89 d0                	mov    %edx,%eax
c0106ffb:	c1 f8 05             	sar    $0x5,%eax
}
c0106ffe:	5d                   	pop    %ebp
c0106fff:	c3                   	ret    

c0107000 <page2pa>:
page2pa(struct Page *page) {
c0107000:	55                   	push   %ebp
c0107001:	89 e5                	mov    %esp,%ebp
c0107003:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0107006:	8b 45 08             	mov    0x8(%ebp),%eax
c0107009:	89 04 24             	mov    %eax,(%esp)
c010700c:	e8 db ff ff ff       	call   c0106fec <page2ppn>
c0107011:	c1 e0 0c             	shl    $0xc,%eax
}
c0107014:	c9                   	leave  
c0107015:	c3                   	ret    

c0107016 <page_ref>:
page_ref(struct Page *page) {
c0107016:	55                   	push   %ebp
c0107017:	89 e5                	mov    %esp,%ebp
    return page->ref;
c0107019:	8b 45 08             	mov    0x8(%ebp),%eax
c010701c:	8b 00                	mov    (%eax),%eax
}
c010701e:	5d                   	pop    %ebp
c010701f:	c3                   	ret    

c0107020 <set_page_ref>:
set_page_ref(struct Page *page, int val) {
c0107020:	55                   	push   %ebp
c0107021:	89 e5                	mov    %esp,%ebp
    page->ref = val;
c0107023:	8b 45 08             	mov    0x8(%ebp),%eax
c0107026:	8b 55 0c             	mov    0xc(%ebp),%edx
c0107029:	89 10                	mov    %edx,(%eax)
}
c010702b:	90                   	nop
c010702c:	5d                   	pop    %ebp
c010702d:	c3                   	ret    

c010702e <default_init>:
#define nr_free (free_area.nr_free)

//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。
//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。
static void
default_init(void) {
c010702e:	f3 0f 1e fb          	endbr32 
c0107032:	55                   	push   %ebp
c0107033:	89 e5                	mov    %esp,%ebp
c0107035:	83 ec 10             	sub    $0x10,%esp
c0107038:	c7 45 fc 64 71 12 c0 	movl   $0xc0127164,-0x4(%ebp)
    elm->prev = elm->next = elm;
c010703f:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0107042:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0107045:	89 50 04             	mov    %edx,0x4(%eax)
c0107048:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010704b:	8b 50 04             	mov    0x4(%eax),%edx
c010704e:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0107051:	89 10                	mov    %edx,(%eax)
}
c0107053:	90                   	nop
    list_init(&free_list);
    nr_free = 0;
c0107054:	c7 05 6c 71 12 c0 00 	movl   $0x0,0xc012716c
c010705b:	00 00 00 
}
c010705e:	90                   	nop
c010705f:	c9                   	leave  
c0107060:	c3                   	ret    

c0107061 <default_init_memmap>:

//用于初始化一段连续的物理页，并将它们加入到空闲内存管理系统中.
//struct Page *base：指向要初始化的页块的起始地址。size_t n：要初始化的页的数量。
static void
default_init_memmap(struct Page *base, size_t n) {
c0107061:	f3 0f 1e fb          	endbr32 
c0107065:	55                   	push   %ebp
c0107066:	89 e5                	mov    %esp,%ebp
c0107068:	83 ec 48             	sub    $0x48,%esp
    assert(n > 0);// 确保请求的页数大于零
c010706b:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010706f:	75 24                	jne    c0107095 <default_init_memmap+0x34>
c0107071:	c7 44 24 0c 3c aa 10 	movl   $0xc010aa3c,0xc(%esp)
c0107078:	c0 
c0107079:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107080:	c0 
c0107081:	c7 44 24 04 9a 00 00 	movl   $0x9a,0x4(%esp)
c0107088:	00 
c0107089:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107090:	e8 b0 93 ff ff       	call   c0100445 <__panic>
    struct Page *p = base;// 指向当前初始化的页
c0107095:	8b 45 08             	mov    0x8(%ebp),%eax
c0107098:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历每一页，设置其状态
    for (; p != base + n; p ++) {
c010709b:	eb 7d                	jmp    c010711a <default_init_memmap+0xb9>
        assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留，函数将抛出错误。
c010709d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01070a0:	83 c0 04             	add    $0x4,%eax
c01070a3:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
c01070aa:	89 45 ec             	mov    %eax,-0x14(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01070ad:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01070b0:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01070b3:	0f a3 10             	bt     %edx,(%eax)
c01070b6:	19 c0                	sbb    %eax,%eax
c01070b8:	89 45 e8             	mov    %eax,-0x18(%ebp)
    return oldbit != 0;
c01070bb:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c01070bf:	0f 95 c0             	setne  %al
c01070c2:	0f b6 c0             	movzbl %al,%eax
c01070c5:	85 c0                	test   %eax,%eax
c01070c7:	75 24                	jne    c01070ed <default_init_memmap+0x8c>
c01070c9:	c7 44 24 0c 6d aa 10 	movl   $0xc010aa6d,0xc(%esp)
c01070d0:	c0 
c01070d1:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01070d8:	c0 
c01070d9:	c7 44 24 04 9e 00 00 	movl   $0x9e,0x4(%esp)
c01070e0:	00 
c01070e1:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01070e8:	e8 58 93 ff ff       	call   c0100445 <__panic>
        p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0，表示该页未分配、未使用。
c01070ed:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01070f0:	c7 40 08 00 00 00 00 	movl   $0x0,0x8(%eax)
c01070f7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01070fa:	8b 50 08             	mov    0x8(%eax),%edx
c01070fd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107100:	89 50 04             	mov    %edx,0x4(%eax)
        set_page_ref(p, 0);//将页的引用计数设置为 0，表明没有任何引用指向此页。
c0107103:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010710a:	00 
c010710b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010710e:	89 04 24             	mov    %eax,(%esp)
c0107111:	e8 0a ff ff ff       	call   c0107020 <set_page_ref>
    for (; p != base + n; p ++) {
c0107116:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
c010711a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010711d:	c1 e0 05             	shl    $0x5,%eax
c0107120:	89 c2                	mov    %eax,%edx
c0107122:	8b 45 08             	mov    0x8(%ebp),%eax
c0107125:	01 d0                	add    %edx,%eax
c0107127:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010712a:	0f 85 6d ff ff ff    	jne    c010709d <default_init_memmap+0x3c>
    }
    // 设置第一个页的 property 为块的总数
    base->property = n;
c0107130:	8b 45 08             	mov    0x8(%ebp),%eax
c0107133:	8b 55 0c             	mov    0xc(%ebp),%edx
c0107136:	89 50 08             	mov    %edx,0x8(%eax)
    SetPageProperty(base);// 设置当前页的有效标志
c0107139:	8b 45 08             	mov    0x8(%ebp),%eax
c010713c:	83 c0 04             	add    $0x4,%eax
c010713f:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c0107146:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0107149:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010714c:	8b 55 d0             	mov    -0x30(%ebp),%edx
c010714f:	0f ab 10             	bts    %edx,(%eax)
}
c0107152:	90                   	nop
    nr_free += n;// 更新空闲页计数
c0107153:	8b 15 6c 71 12 c0    	mov    0xc012716c,%edx
c0107159:	8b 45 0c             	mov    0xc(%ebp),%eax
c010715c:	01 d0                	add    %edx,%eax
c010715e:	a3 6c 71 12 c0       	mov    %eax,0xc012716c
    list_add_before(&free_list, &(base->page_link));// 将该块添加到空闲列表中
c0107163:	8b 45 08             	mov    0x8(%ebp),%eax
c0107166:	83 c0 0c             	add    $0xc,%eax
c0107169:	c7 45 e4 64 71 12 c0 	movl   $0xc0127164,-0x1c(%ebp)
c0107170:	89 45 e0             	mov    %eax,-0x20(%ebp)
    __list_add(elm, listelm->prev, listelm);
c0107173:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107176:	8b 00                	mov    (%eax),%eax
c0107178:	8b 55 e0             	mov    -0x20(%ebp),%edx
c010717b:	89 55 dc             	mov    %edx,-0x24(%ebp)
c010717e:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0107181:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107184:	89 45 d4             	mov    %eax,-0x2c(%ebp)
    prev->next = next->prev = elm;
c0107187:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c010718a:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010718d:	89 10                	mov    %edx,(%eax)
c010718f:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107192:	8b 10                	mov    (%eax),%edx
c0107194:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0107197:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c010719a:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010719d:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01071a0:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c01071a3:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01071a6:	8b 55 d8             	mov    -0x28(%ebp),%edx
c01071a9:	89 10                	mov    %edx,(%eax)
}
c01071ab:	90                   	nop
}
c01071ac:	90                   	nop
}
c01071ad:	90                   	nop
c01071ae:	c9                   	leave  
c01071af:	c3                   	ret    

c01071b0 <default_alloc_pages>:

//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。
static struct Page *
default_alloc_pages(size_t n) {
c01071b0:	f3 0f 1e fb          	endbr32 
c01071b4:	55                   	push   %ebp
c01071b5:	89 e5                	mov    %esp,%ebp
c01071b7:	83 ec 68             	sub    $0x68,%esp
    assert(n > 0);// 确保请求的页数大于零
c01071ba:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c01071be:	75 24                	jne    c01071e4 <default_alloc_pages+0x34>
c01071c0:	c7 44 24 0c 3c aa 10 	movl   $0xc010aa3c,0xc(%esp)
c01071c7:	c0 
c01071c8:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01071cf:	c0 
c01071d0:	c7 44 24 04 ac 00 00 	movl   $0xac,0x4(%esp)
c01071d7:	00 
c01071d8:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01071df:	e8 61 92 ff ff       	call   c0100445 <__panic>
    if (n > nr_free) {// 检查请求的页数是否超过空闲页数
c01071e4:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c01071e9:	39 45 08             	cmp    %eax,0x8(%ebp)
c01071ec:	76 0a                	jbe    c01071f8 <default_alloc_pages+0x48>
        return NULL;
c01071ee:	b8 00 00 00 00       	mov    $0x0,%eax
c01071f3:	e9 3c 01 00 00       	jmp    c0107334 <default_alloc_pages+0x184>
    }
    struct Page *page = NULL;// 初始化分配的页指针
c01071f8:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    list_entry_t *le = &free_list;// 初始化链表迭代器
c01071ff:	c7 45 f0 64 71 12 c0 	movl   $0xc0127164,-0x10(%ebp)
    // 遍历空闲列表，寻找第一个满足条件的块
    while ((le = list_next(le)) != &free_list) {
c0107206:	eb 1c                	jmp    c0107224 <default_alloc_pages+0x74>
        struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体
c0107208:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010720b:	83 e8 0c             	sub    $0xc,%eax
c010720e:	89 45 ec             	mov    %eax,-0x14(%ebp)
        if (p->property >= n) {// 检查当前块的页数是否满足请求
c0107211:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107214:	8b 40 08             	mov    0x8(%eax),%eax
c0107217:	39 45 08             	cmp    %eax,0x8(%ebp)
c010721a:	77 08                	ja     c0107224 <default_alloc_pages+0x74>
            page = p;// 找到合适的块
c010721c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010721f:	89 45 f4             	mov    %eax,-0xc(%ebp)
            break;// 退出循环
c0107222:	eb 18                	jmp    c010723c <default_alloc_pages+0x8c>
c0107224:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107227:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    return listelm->next;
c010722a:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010722d:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c0107230:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0107233:	81 7d f0 64 71 12 c0 	cmpl   $0xc0127164,-0x10(%ebp)
c010723a:	75 cc                	jne    c0107208 <default_alloc_pages+0x58>
        }
    }
    if (page != NULL) {// 如果找到合适的块
c010723c:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107240:	0f 84 eb 00 00 00    	je     c0107331 <default_alloc_pages+0x181>
        //list_del(&(page->page_link));// 从空闲列表中删除该块
        if (page->property > n) {
c0107246:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107249:	8b 40 08             	mov    0x8(%eax),%eax
c010724c:	39 45 08             	cmp    %eax,0x8(%ebp)
c010724f:	0f 83 88 00 00 00    	jae    c01072dd <default_alloc_pages+0x12d>
            struct Page *p = page + n;// 指向剩余的页
c0107255:	8b 45 08             	mov    0x8(%ebp),%eax
c0107258:	c1 e0 05             	shl    $0x5,%eax
c010725b:	89 c2                	mov    %eax,%edx
c010725d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107260:	01 d0                	add    %edx,%eax
c0107262:	89 45 e8             	mov    %eax,-0x18(%ebp)
            p->property = page->property - n;// 更新剩余块的页数
c0107265:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107268:	8b 40 08             	mov    0x8(%eax),%eax
c010726b:	2b 45 08             	sub    0x8(%ebp),%eax
c010726e:	89 c2                	mov    %eax,%edx
c0107270:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107273:	89 50 08             	mov    %edx,0x8(%eax)
            SetPageProperty(p);
c0107276:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107279:	83 c0 04             	add    $0x4,%eax
c010727c:	c7 45 cc 01 00 00 00 	movl   $0x1,-0x34(%ebp)
c0107283:	89 45 c8             	mov    %eax,-0x38(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0107286:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0107289:	8b 55 cc             	mov    -0x34(%ebp),%edx
c010728c:	0f ab 10             	bts    %edx,(%eax)
}
c010728f:	90                   	nop
            list_add_after(&(page->page_link), &(p->page_link));// 将剩余块添加回空闲列表
c0107290:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107293:	83 c0 0c             	add    $0xc,%eax
c0107296:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0107299:	83 c2 0c             	add    $0xc,%edx
c010729c:	89 55 e0             	mov    %edx,-0x20(%ebp)
c010729f:	89 45 dc             	mov    %eax,-0x24(%ebp)
    __list_add(elm, listelm, listelm->next);
c01072a2:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01072a5:	8b 40 04             	mov    0x4(%eax),%eax
c01072a8:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01072ab:	89 55 d8             	mov    %edx,-0x28(%ebp)
c01072ae:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01072b1:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c01072b4:	89 45 d0             	mov    %eax,-0x30(%ebp)
    prev->next = next->prev = elm;
c01072b7:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01072ba:	8b 55 d8             	mov    -0x28(%ebp),%edx
c01072bd:	89 10                	mov    %edx,(%eax)
c01072bf:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01072c2:	8b 10                	mov    (%eax),%edx
c01072c4:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01072c7:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c01072ca:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01072cd:	8b 55 d0             	mov    -0x30(%ebp),%edx
c01072d0:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c01072d3:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01072d6:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01072d9:	89 10                	mov    %edx,(%eax)
}
c01072db:	90                   	nop
}
c01072dc:	90                   	nop
    }
        list_del(&(page->page_link));
c01072dd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01072e0:	83 c0 0c             	add    $0xc,%eax
c01072e3:	89 45 bc             	mov    %eax,-0x44(%ebp)
    __list_del(listelm->prev, listelm->next);
c01072e6:	8b 45 bc             	mov    -0x44(%ebp),%eax
c01072e9:	8b 40 04             	mov    0x4(%eax),%eax
c01072ec:	8b 55 bc             	mov    -0x44(%ebp),%edx
c01072ef:	8b 12                	mov    (%edx),%edx
c01072f1:	89 55 b8             	mov    %edx,-0x48(%ebp)
c01072f4:	89 45 b4             	mov    %eax,-0x4c(%ebp)
    prev->next = next;
c01072f7:	8b 45 b8             	mov    -0x48(%ebp),%eax
c01072fa:	8b 55 b4             	mov    -0x4c(%ebp),%edx
c01072fd:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0107300:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0107303:	8b 55 b8             	mov    -0x48(%ebp),%edx
c0107306:	89 10                	mov    %edx,(%eax)
}
c0107308:	90                   	nop
}
c0107309:	90                   	nop
        nr_free -= n;// 减少空闲页的计数
c010730a:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c010730f:	2b 45 08             	sub    0x8(%ebp),%eax
c0107312:	a3 6c 71 12 c0       	mov    %eax,0xc012716c
        ClearPageProperty(page);// 清除已分配页的属性
c0107317:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010731a:	83 c0 04             	add    $0x4,%eax
c010731d:	c7 45 c4 01 00 00 00 	movl   $0x1,-0x3c(%ebp)
c0107324:	89 45 c0             	mov    %eax,-0x40(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0107327:	8b 45 c0             	mov    -0x40(%ebp),%eax
c010732a:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c010732d:	0f b3 10             	btr    %edx,(%eax)
}
c0107330:	90                   	nop
    }
    return page;// 返回分配的页块
c0107331:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0107334:	c9                   	leave  
c0107335:	c3                   	ret    

c0107336 <default_free_pages>:

static void
default_free_pages(struct Page *base, size_t n) {
c0107336:	f3 0f 1e fb          	endbr32 
c010733a:	55                   	push   %ebp
c010733b:	89 e5                	mov    %esp,%ebp
c010733d:	81 ec 98 00 00 00    	sub    $0x98,%esp
    assert(n > 0);// 确保请求释放的页数大于零
c0107343:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0107347:	75 24                	jne    c010736d <default_free_pages+0x37>
c0107349:	c7 44 24 0c 3c aa 10 	movl   $0xc010aa3c,0xc(%esp)
c0107350:	c0 
c0107351:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107358:	c0 
c0107359:	c7 44 24 04 cb 00 00 	movl   $0xcb,0x4(%esp)
c0107360:	00 
c0107361:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107368:	e8 d8 90 ff ff       	call   c0100445 <__panic>
    struct Page *p = base;
c010736d:	8b 45 08             	mov    0x8(%ebp),%eax
c0107370:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历释放的页，检查状态并重置
    for (; p != base + n; p ++) {
c0107373:	e9 9d 00 00 00       	jmp    c0107415 <default_free_pages+0xdf>
        assert(!PageReserved(p) && !PageProperty(p));// 确保页没有被保留并且没有属性
c0107378:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010737b:	83 c0 04             	add    $0x4,%eax
c010737e:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0107385:	89 45 e8             	mov    %eax,-0x18(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0107388:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010738b:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010738e:	0f a3 10             	bt     %edx,(%eax)
c0107391:	19 c0                	sbb    %eax,%eax
c0107393:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    return oldbit != 0;
c0107396:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c010739a:	0f 95 c0             	setne  %al
c010739d:	0f b6 c0             	movzbl %al,%eax
c01073a0:	85 c0                	test   %eax,%eax
c01073a2:	75 2c                	jne    c01073d0 <default_free_pages+0x9a>
c01073a4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01073a7:	83 c0 04             	add    $0x4,%eax
c01073aa:	c7 45 e0 01 00 00 00 	movl   $0x1,-0x20(%ebp)
c01073b1:	89 45 dc             	mov    %eax,-0x24(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01073b4:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01073b7:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01073ba:	0f a3 10             	bt     %edx,(%eax)
c01073bd:	19 c0                	sbb    %eax,%eax
c01073bf:	89 45 d8             	mov    %eax,-0x28(%ebp)
    return oldbit != 0;
c01073c2:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c01073c6:	0f 95 c0             	setne  %al
c01073c9:	0f b6 c0             	movzbl %al,%eax
c01073cc:	85 c0                	test   %eax,%eax
c01073ce:	74 24                	je     c01073f4 <default_free_pages+0xbe>
c01073d0:	c7 44 24 0c 80 aa 10 	movl   $0xc010aa80,0xc(%esp)
c01073d7:	c0 
c01073d8:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01073df:	c0 
c01073e0:	c7 44 24 04 cf 00 00 	movl   $0xcf,0x4(%esp)
c01073e7:	00 
c01073e8:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01073ef:	e8 51 90 ff ff       	call   c0100445 <__panic>
        p->flags = 0;// 清除 flags 字段
c01073f4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01073f7:	c7 40 04 00 00 00 00 	movl   $0x0,0x4(%eax)
        set_page_ref(p, 0);// 清除引用计数
c01073fe:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0107405:	00 
c0107406:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107409:	89 04 24             	mov    %eax,(%esp)
c010740c:	e8 0f fc ff ff       	call   c0107020 <set_page_ref>
    for (; p != base + n; p ++) {
c0107411:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
c0107415:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107418:	c1 e0 05             	shl    $0x5,%eax
c010741b:	89 c2                	mov    %eax,%edx
c010741d:	8b 45 08             	mov    0x8(%ebp),%eax
c0107420:	01 d0                	add    %edx,%eax
c0107422:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0107425:	0f 85 4d ff ff ff    	jne    c0107378 <default_free_pages+0x42>
    }
    // 设置基页的属性为释放的页数
    base->property = n;
c010742b:	8b 45 08             	mov    0x8(%ebp),%eax
c010742e:	8b 55 0c             	mov    0xc(%ebp),%edx
c0107431:	89 50 08             	mov    %edx,0x8(%eax)
    SetPageProperty(base);// 设置页的有效标志
c0107434:	8b 45 08             	mov    0x8(%ebp),%eax
c0107437:	83 c0 04             	add    $0x4,%eax
c010743a:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c0107441:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0107444:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0107447:	8b 55 d0             	mov    -0x30(%ebp),%edx
c010744a:	0f ab 10             	bts    %edx,(%eax)
}
c010744d:	90                   	nop
c010744e:	c7 45 d4 64 71 12 c0 	movl   $0xc0127164,-0x2c(%ebp)
    return listelm->next;
c0107455:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107458:	8b 40 04             	mov    0x4(%eax),%eax
    // 遍历空闲列表，检查是否需要合并
    list_entry_t *le = list_next(&free_list);
c010745b:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list) {
c010745e:	e9 00 01 00 00       	jmp    c0107563 <default_free_pages+0x22d>
        p = le2page(le, page_link);
c0107463:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107466:	83 e8 0c             	sub    $0xc,%eax
c0107469:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010746c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010746f:	89 45 c8             	mov    %eax,-0x38(%ebp)
c0107472:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0107475:	8b 40 04             	mov    0x4(%eax),%eax
        le = list_next(le);
c0107478:	89 45 f0             	mov    %eax,-0x10(%ebp)
        // 如果当前页块与释放的页块相邻，合并
        if (base + base->property == p) {
c010747b:	8b 45 08             	mov    0x8(%ebp),%eax
c010747e:	8b 40 08             	mov    0x8(%eax),%eax
c0107481:	c1 e0 05             	shl    $0x5,%eax
c0107484:	89 c2                	mov    %eax,%edx
c0107486:	8b 45 08             	mov    0x8(%ebp),%eax
c0107489:	01 d0                	add    %edx,%eax
c010748b:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010748e:	75 5d                	jne    c01074ed <default_free_pages+0x1b7>
            base->property += p->property;// 合并当前页块
c0107490:	8b 45 08             	mov    0x8(%ebp),%eax
c0107493:	8b 50 08             	mov    0x8(%eax),%edx
c0107496:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107499:	8b 40 08             	mov    0x8(%eax),%eax
c010749c:	01 c2                	add    %eax,%edx
c010749e:	8b 45 08             	mov    0x8(%ebp),%eax
c01074a1:	89 50 08             	mov    %edx,0x8(%eax)
            ClearPageProperty(p);// 清除合并页的属性
c01074a4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01074a7:	83 c0 04             	add    $0x4,%eax
c01074aa:	c7 45 b8 01 00 00 00 	movl   $0x1,-0x48(%ebp)
c01074b1:	89 45 b4             	mov    %eax,-0x4c(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c01074b4:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c01074b7:	8b 55 b8             	mov    -0x48(%ebp),%edx
c01074ba:	0f b3 10             	btr    %edx,(%eax)
}
c01074bd:	90                   	nop
            list_del(&(p->page_link));// 从空闲列表中删除合并页
c01074be:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01074c1:	83 c0 0c             	add    $0xc,%eax
c01074c4:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    __list_del(listelm->prev, listelm->next);
c01074c7:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c01074ca:	8b 40 04             	mov    0x4(%eax),%eax
c01074cd:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c01074d0:	8b 12                	mov    (%edx),%edx
c01074d2:	89 55 c0             	mov    %edx,-0x40(%ebp)
c01074d5:	89 45 bc             	mov    %eax,-0x44(%ebp)
    prev->next = next;
c01074d8:	8b 45 c0             	mov    -0x40(%ebp),%eax
c01074db:	8b 55 bc             	mov    -0x44(%ebp),%edx
c01074de:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c01074e1:	8b 45 bc             	mov    -0x44(%ebp),%eax
c01074e4:	8b 55 c0             	mov    -0x40(%ebp),%edx
c01074e7:	89 10                	mov    %edx,(%eax)
}
c01074e9:	90                   	nop
}
c01074ea:	90                   	nop
c01074eb:	eb 76                	jmp    c0107563 <default_free_pages+0x22d>
        }
        else if (p + p->property == base) {
c01074ed:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01074f0:	8b 40 08             	mov    0x8(%eax),%eax
c01074f3:	c1 e0 05             	shl    $0x5,%eax
c01074f6:	89 c2                	mov    %eax,%edx
c01074f8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01074fb:	01 d0                	add    %edx,%eax
c01074fd:	39 45 08             	cmp    %eax,0x8(%ebp)
c0107500:	75 61                	jne    c0107563 <default_free_pages+0x22d>
            p->property += base->property;// 合并前一个页块
c0107502:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107505:	8b 50 08             	mov    0x8(%eax),%edx
c0107508:	8b 45 08             	mov    0x8(%ebp),%eax
c010750b:	8b 40 08             	mov    0x8(%eax),%eax
c010750e:	01 c2                	add    %eax,%edx
c0107510:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107513:	89 50 08             	mov    %edx,0x8(%eax)
            ClearPageProperty(base);// 清除当前页的属性
c0107516:	8b 45 08             	mov    0x8(%ebp),%eax
c0107519:	83 c0 04             	add    $0x4,%eax
c010751c:	c7 45 a4 01 00 00 00 	movl   $0x1,-0x5c(%ebp)
c0107523:	89 45 a0             	mov    %eax,-0x60(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0107526:	8b 45 a0             	mov    -0x60(%ebp),%eax
c0107529:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c010752c:	0f b3 10             	btr    %edx,(%eax)
}
c010752f:	90                   	nop
            base = p;// 更新 base 指针
c0107530:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107533:	89 45 08             	mov    %eax,0x8(%ebp)
            list_del(&(p->page_link));// 从空闲列表中删除当前页
c0107536:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107539:	83 c0 0c             	add    $0xc,%eax
c010753c:	89 45 b0             	mov    %eax,-0x50(%ebp)
    __list_del(listelm->prev, listelm->next);
c010753f:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0107542:	8b 40 04             	mov    0x4(%eax),%eax
c0107545:	8b 55 b0             	mov    -0x50(%ebp),%edx
c0107548:	8b 12                	mov    (%edx),%edx
c010754a:	89 55 ac             	mov    %edx,-0x54(%ebp)
c010754d:	89 45 a8             	mov    %eax,-0x58(%ebp)
    prev->next = next;
c0107550:	8b 45 ac             	mov    -0x54(%ebp),%eax
c0107553:	8b 55 a8             	mov    -0x58(%ebp),%edx
c0107556:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0107559:	8b 45 a8             	mov    -0x58(%ebp),%eax
c010755c:	8b 55 ac             	mov    -0x54(%ebp),%edx
c010755f:	89 10                	mov    %edx,(%eax)
}
c0107561:	90                   	nop
}
c0107562:	90                   	nop
    while (le != &free_list) {
c0107563:	81 7d f0 64 71 12 c0 	cmpl   $0xc0127164,-0x10(%ebp)
c010756a:	0f 85 f3 fe ff ff    	jne    c0107463 <default_free_pages+0x12d>
        }
    }
    nr_free += n;// 更新空闲页的计数
c0107570:	8b 15 6c 71 12 c0    	mov    0xc012716c,%edx
c0107576:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107579:	01 d0                	add    %edx,%eax
c010757b:	a3 6c 71 12 c0       	mov    %eax,0xc012716c
c0107580:	c7 45 9c 64 71 12 c0 	movl   $0xc0127164,-0x64(%ebp)
    return listelm->next;
c0107587:	8b 45 9c             	mov    -0x64(%ebp),%eax
c010758a:	8b 40 04             	mov    0x4(%eax),%eax
    le = list_next(&free_list);
c010758d:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list)
c0107590:	eb 66                	jmp    c01075f8 <default_free_pages+0x2c2>
    {
        p = le2page(le, page_link);
c0107592:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107595:	83 e8 0c             	sub    $0xc,%eax
c0107598:	89 45 f4             	mov    %eax,-0xc(%ebp)
        if (base + base->property <= p)
c010759b:	8b 45 08             	mov    0x8(%ebp),%eax
c010759e:	8b 40 08             	mov    0x8(%eax),%eax
c01075a1:	c1 e0 05             	shl    $0x5,%eax
c01075a4:	89 c2                	mov    %eax,%edx
c01075a6:	8b 45 08             	mov    0x8(%ebp),%eax
c01075a9:	01 d0                	add    %edx,%eax
c01075ab:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c01075ae:	72 39                	jb     c01075e9 <default_free_pages+0x2b3>
        {
            assert(base + base->property != p);
c01075b0:	8b 45 08             	mov    0x8(%ebp),%eax
c01075b3:	8b 40 08             	mov    0x8(%eax),%eax
c01075b6:	c1 e0 05             	shl    $0x5,%eax
c01075b9:	89 c2                	mov    %eax,%edx
c01075bb:	8b 45 08             	mov    0x8(%ebp),%eax
c01075be:	01 d0                	add    %edx,%eax
c01075c0:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c01075c3:	75 3e                	jne    c0107603 <default_free_pages+0x2cd>
c01075c5:	c7 44 24 0c a5 aa 10 	movl   $0xc010aaa5,0xc(%esp)
c01075cc:	c0 
c01075cd:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01075d4:	c0 
c01075d5:	c7 44 24 04 ef 00 00 	movl   $0xef,0x4(%esp)
c01075dc:	00 
c01075dd:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01075e4:	e8 5c 8e ff ff       	call   c0100445 <__panic>
c01075e9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01075ec:	89 45 98             	mov    %eax,-0x68(%ebp)
c01075ef:	8b 45 98             	mov    -0x68(%ebp),%eax
c01075f2:	8b 40 04             	mov    0x4(%eax),%eax
            break;
        }
        le = list_next(le);    
c01075f5:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list)
c01075f8:	81 7d f0 64 71 12 c0 	cmpl   $0xc0127164,-0x10(%ebp)
c01075ff:	75 91                	jne    c0107592 <default_free_pages+0x25c>
c0107601:	eb 01                	jmp    c0107604 <default_free_pages+0x2ce>
            break;
c0107603:	90                   	nop
    }
    
    list_add_before(le, &(base->page_link));// 将释放的页块添加到空闲列表中
c0107604:	8b 45 08             	mov    0x8(%ebp),%eax
c0107607:	8d 50 0c             	lea    0xc(%eax),%edx
c010760a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010760d:	89 45 94             	mov    %eax,-0x6c(%ebp)
c0107610:	89 55 90             	mov    %edx,-0x70(%ebp)
    __list_add(elm, listelm->prev, listelm);
c0107613:	8b 45 94             	mov    -0x6c(%ebp),%eax
c0107616:	8b 00                	mov    (%eax),%eax
c0107618:	8b 55 90             	mov    -0x70(%ebp),%edx
c010761b:	89 55 8c             	mov    %edx,-0x74(%ebp)
c010761e:	89 45 88             	mov    %eax,-0x78(%ebp)
c0107621:	8b 45 94             	mov    -0x6c(%ebp),%eax
c0107624:	89 45 84             	mov    %eax,-0x7c(%ebp)
    prev->next = next->prev = elm;
c0107627:	8b 45 84             	mov    -0x7c(%ebp),%eax
c010762a:	8b 55 8c             	mov    -0x74(%ebp),%edx
c010762d:	89 10                	mov    %edx,(%eax)
c010762f:	8b 45 84             	mov    -0x7c(%ebp),%eax
c0107632:	8b 10                	mov    (%eax),%edx
c0107634:	8b 45 88             	mov    -0x78(%ebp),%eax
c0107637:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c010763a:	8b 45 8c             	mov    -0x74(%ebp),%eax
c010763d:	8b 55 84             	mov    -0x7c(%ebp),%edx
c0107640:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0107643:	8b 45 8c             	mov    -0x74(%ebp),%eax
c0107646:	8b 55 88             	mov    -0x78(%ebp),%edx
c0107649:	89 10                	mov    %edx,(%eax)
}
c010764b:	90                   	nop
}
c010764c:	90                   	nop
}
c010764d:	90                   	nop
c010764e:	c9                   	leave  
c010764f:	c3                   	ret    

c0107650 <default_nr_free_pages>:

//用于返回当前系统中可用的空闲页的数量。
static size_t
default_nr_free_pages(void) {
c0107650:	f3 0f 1e fb          	endbr32 
c0107654:	55                   	push   %ebp
c0107655:	89 e5                	mov    %esp,%ebp
    return nr_free;// 返回当前空闲页的数量
c0107657:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
}
c010765c:	5d                   	pop    %ebp
c010765d:	c3                   	ret    

c010765e <basic_check>:

//basic_check 函数用于测试内存分配和释放的基本功能，
//确保在不同情况下内存管理系统的正确性，包括分配、释放、合并和引用计数等操作。
static void
basic_check(void) {
c010765e:	f3 0f 1e fb          	endbr32 
c0107662:	55                   	push   %ebp
c0107663:	89 e5                	mov    %esp,%ebp
c0107665:	83 ec 48             	sub    $0x48,%esp
    struct Page *p0, *p1, *p2;
    p0 = p1 = p2 = NULL;
c0107668:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c010766f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107672:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0107675:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107678:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 分配三个页面
    assert((p0 = alloc_page()) != NULL);
c010767b:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0107682:	e8 18 c1 ff ff       	call   c010379f <alloc_pages>
c0107687:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010768a:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c010768e:	75 24                	jne    c01076b4 <basic_check+0x56>
c0107690:	c7 44 24 0c c0 aa 10 	movl   $0xc010aac0,0xc(%esp)
c0107697:	c0 
c0107698:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c010769f:	c0 
c01076a0:	c7 44 24 04 05 01 00 	movl   $0x105,0x4(%esp)
c01076a7:	00 
c01076a8:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01076af:	e8 91 8d ff ff       	call   c0100445 <__panic>
    assert((p1 = alloc_page()) != NULL);
c01076b4:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01076bb:	e8 df c0 ff ff       	call   c010379f <alloc_pages>
c01076c0:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01076c3:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01076c7:	75 24                	jne    c01076ed <basic_check+0x8f>
c01076c9:	c7 44 24 0c dc aa 10 	movl   $0xc010aadc,0xc(%esp)
c01076d0:	c0 
c01076d1:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01076d8:	c0 
c01076d9:	c7 44 24 04 06 01 00 	movl   $0x106,0x4(%esp)
c01076e0:	00 
c01076e1:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01076e8:	e8 58 8d ff ff       	call   c0100445 <__panic>
    assert((p2 = alloc_page()) != NULL);
c01076ed:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01076f4:	e8 a6 c0 ff ff       	call   c010379f <alloc_pages>
c01076f9:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01076fc:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107700:	75 24                	jne    c0107726 <basic_check+0xc8>
c0107702:	c7 44 24 0c f8 aa 10 	movl   $0xc010aaf8,0xc(%esp)
c0107709:	c0 
c010770a:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107711:	c0 
c0107712:	c7 44 24 04 07 01 00 	movl   $0x107,0x4(%esp)
c0107719:	00 
c010771a:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107721:	e8 1f 8d ff ff       	call   c0100445 <__panic>
     // 确保所有分配的页面是不同的
    assert(p0 != p1 && p0 != p2 && p1 != p2);
c0107726:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107729:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c010772c:	74 10                	je     c010773e <basic_check+0xe0>
c010772e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107731:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0107734:	74 08                	je     c010773e <basic_check+0xe0>
c0107736:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107739:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c010773c:	75 24                	jne    c0107762 <basic_check+0x104>
c010773e:	c7 44 24 0c 14 ab 10 	movl   $0xc010ab14,0xc(%esp)
c0107745:	c0 
c0107746:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c010774d:	c0 
c010774e:	c7 44 24 04 09 01 00 	movl   $0x109,0x4(%esp)
c0107755:	00 
c0107756:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c010775d:	e8 e3 8c ff ff       	call   c0100445 <__panic>
    // 确保页面的引用计数为 0
    assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0);
c0107762:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107765:	89 04 24             	mov    %eax,(%esp)
c0107768:	e8 a9 f8 ff ff       	call   c0107016 <page_ref>
c010776d:	85 c0                	test   %eax,%eax
c010776f:	75 1e                	jne    c010778f <basic_check+0x131>
c0107771:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107774:	89 04 24             	mov    %eax,(%esp)
c0107777:	e8 9a f8 ff ff       	call   c0107016 <page_ref>
c010777c:	85 c0                	test   %eax,%eax
c010777e:	75 0f                	jne    c010778f <basic_check+0x131>
c0107780:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107783:	89 04 24             	mov    %eax,(%esp)
c0107786:	e8 8b f8 ff ff       	call   c0107016 <page_ref>
c010778b:	85 c0                	test   %eax,%eax
c010778d:	74 24                	je     c01077b3 <basic_check+0x155>
c010778f:	c7 44 24 0c 38 ab 10 	movl   $0xc010ab38,0xc(%esp)
c0107796:	c0 
c0107797:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c010779e:	c0 
c010779f:	c7 44 24 04 0b 01 00 	movl   $0x10b,0x4(%esp)
c01077a6:	00 
c01077a7:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01077ae:	e8 92 8c ff ff       	call   c0100445 <__panic>
    // 确保页面地址在合法范围内
    assert(page2pa(p0) < npage * PGSIZE);
c01077b3:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01077b6:	89 04 24             	mov    %eax,(%esp)
c01077b9:	e8 42 f8 ff ff       	call   c0107000 <page2pa>
c01077be:	8b 15 80 6f 12 c0    	mov    0xc0126f80,%edx
c01077c4:	c1 e2 0c             	shl    $0xc,%edx
c01077c7:	39 d0                	cmp    %edx,%eax
c01077c9:	72 24                	jb     c01077ef <basic_check+0x191>
c01077cb:	c7 44 24 0c 74 ab 10 	movl   $0xc010ab74,0xc(%esp)
c01077d2:	c0 
c01077d3:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01077da:	c0 
c01077db:	c7 44 24 04 0d 01 00 	movl   $0x10d,0x4(%esp)
c01077e2:	00 
c01077e3:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01077ea:	e8 56 8c ff ff       	call   c0100445 <__panic>
    assert(page2pa(p1) < npage * PGSIZE);
c01077ef:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01077f2:	89 04 24             	mov    %eax,(%esp)
c01077f5:	e8 06 f8 ff ff       	call   c0107000 <page2pa>
c01077fa:	8b 15 80 6f 12 c0    	mov    0xc0126f80,%edx
c0107800:	c1 e2 0c             	shl    $0xc,%edx
c0107803:	39 d0                	cmp    %edx,%eax
c0107805:	72 24                	jb     c010782b <basic_check+0x1cd>
c0107807:	c7 44 24 0c 91 ab 10 	movl   $0xc010ab91,0xc(%esp)
c010780e:	c0 
c010780f:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107816:	c0 
c0107817:	c7 44 24 04 0e 01 00 	movl   $0x10e,0x4(%esp)
c010781e:	00 
c010781f:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107826:	e8 1a 8c ff ff       	call   c0100445 <__panic>
    assert(page2pa(p2) < npage * PGSIZE);
c010782b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010782e:	89 04 24             	mov    %eax,(%esp)
c0107831:	e8 ca f7 ff ff       	call   c0107000 <page2pa>
c0107836:	8b 15 80 6f 12 c0    	mov    0xc0126f80,%edx
c010783c:	c1 e2 0c             	shl    $0xc,%edx
c010783f:	39 d0                	cmp    %edx,%eax
c0107841:	72 24                	jb     c0107867 <basic_check+0x209>
c0107843:	c7 44 24 0c ae ab 10 	movl   $0xc010abae,0xc(%esp)
c010784a:	c0 
c010784b:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107852:	c0 
c0107853:	c7 44 24 04 0f 01 00 	movl   $0x10f,0x4(%esp)
c010785a:	00 
c010785b:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107862:	e8 de 8b ff ff       	call   c0100445 <__panic>
    // 保存当前的空闲页面链表和数量
    list_entry_t free_list_store = free_list;
c0107867:	a1 64 71 12 c0       	mov    0xc0127164,%eax
c010786c:	8b 15 68 71 12 c0    	mov    0xc0127168,%edx
c0107872:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0107875:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0107878:	c7 45 dc 64 71 12 c0 	movl   $0xc0127164,-0x24(%ebp)
    elm->prev = elm->next = elm;
c010787f:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0107882:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0107885:	89 50 04             	mov    %edx,0x4(%eax)
c0107888:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010788b:	8b 50 04             	mov    0x4(%eax),%edx
c010788e:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0107891:	89 10                	mov    %edx,(%eax)
}
c0107893:	90                   	nop
c0107894:	c7 45 e0 64 71 12 c0 	movl   $0xc0127164,-0x20(%ebp)
    return list->next == list;
c010789b:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010789e:	8b 40 04             	mov    0x4(%eax),%eax
c01078a1:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c01078a4:	0f 94 c0             	sete   %al
c01078a7:	0f b6 c0             	movzbl %al,%eax
    list_init(&free_list);// 初始化空闲列表
    assert(list_empty(&free_list));// 确保空闲列表为空
c01078aa:	85 c0                	test   %eax,%eax
c01078ac:	75 24                	jne    c01078d2 <basic_check+0x274>
c01078ae:	c7 44 24 0c cb ab 10 	movl   $0xc010abcb,0xc(%esp)
c01078b5:	c0 
c01078b6:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01078bd:	c0 
c01078be:	c7 44 24 04 13 01 00 	movl   $0x113,0x4(%esp)
c01078c5:	00 
c01078c6:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01078cd:	e8 73 8b ff ff       	call   c0100445 <__panic>

    unsigned int nr_free_store = nr_free;// 保存当前空闲页数量
c01078d2:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c01078d7:	89 45 e8             	mov    %eax,-0x18(%ebp)
    nr_free = 0;// 将空闲页数量设为 0
c01078da:	c7 05 6c 71 12 c0 00 	movl   $0x0,0xc012716c
c01078e1:	00 00 00 
    // 请求分配页面，但当前没有空闲页面
    assert(alloc_page() == NULL);
c01078e4:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01078eb:	e8 af be ff ff       	call   c010379f <alloc_pages>
c01078f0:	85 c0                	test   %eax,%eax
c01078f2:	74 24                	je     c0107918 <basic_check+0x2ba>
c01078f4:	c7 44 24 0c e2 ab 10 	movl   $0xc010abe2,0xc(%esp)
c01078fb:	c0 
c01078fc:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107903:	c0 
c0107904:	c7 44 24 04 18 01 00 	movl   $0x118,0x4(%esp)
c010790b:	00 
c010790c:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107913:	e8 2d 8b ff ff       	call   c0100445 <__panic>
    // 释放之前分配的页面
    free_page(p0);
c0107918:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010791f:	00 
c0107920:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107923:	89 04 24             	mov    %eax,(%esp)
c0107926:	e8 e3 be ff ff       	call   c010380e <free_pages>
    free_page(p1);
c010792b:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107932:	00 
c0107933:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107936:	89 04 24             	mov    %eax,(%esp)
c0107939:	e8 d0 be ff ff       	call   c010380e <free_pages>
    free_page(p2);
c010793e:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107945:	00 
c0107946:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107949:	89 04 24             	mov    %eax,(%esp)
c010794c:	e8 bd be ff ff       	call   c010380e <free_pages>
    assert(nr_free == 3);// 确保释放后空闲页数量为 3
c0107951:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c0107956:	83 f8 03             	cmp    $0x3,%eax
c0107959:	74 24                	je     c010797f <basic_check+0x321>
c010795b:	c7 44 24 0c f7 ab 10 	movl   $0xc010abf7,0xc(%esp)
c0107962:	c0 
c0107963:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c010796a:	c0 
c010796b:	c7 44 24 04 1d 01 00 	movl   $0x11d,0x4(%esp)
c0107972:	00 
c0107973:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c010797a:	e8 c6 8a ff ff       	call   c0100445 <__panic>
    // 再次分配三个页面
    assert((p0 = alloc_page()) != NULL);
c010797f:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0107986:	e8 14 be ff ff       	call   c010379f <alloc_pages>
c010798b:	89 45 ec             	mov    %eax,-0x14(%ebp)
c010798e:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0107992:	75 24                	jne    c01079b8 <basic_check+0x35a>
c0107994:	c7 44 24 0c c0 aa 10 	movl   $0xc010aac0,0xc(%esp)
c010799b:	c0 
c010799c:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01079a3:	c0 
c01079a4:	c7 44 24 04 1f 01 00 	movl   $0x11f,0x4(%esp)
c01079ab:	00 
c01079ac:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01079b3:	e8 8d 8a ff ff       	call   c0100445 <__panic>
    assert((p1 = alloc_page()) != NULL);
c01079b8:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01079bf:	e8 db bd ff ff       	call   c010379f <alloc_pages>
c01079c4:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01079c7:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01079cb:	75 24                	jne    c01079f1 <basic_check+0x393>
c01079cd:	c7 44 24 0c dc aa 10 	movl   $0xc010aadc,0xc(%esp)
c01079d4:	c0 
c01079d5:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01079dc:	c0 
c01079dd:	c7 44 24 04 20 01 00 	movl   $0x120,0x4(%esp)
c01079e4:	00 
c01079e5:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01079ec:	e8 54 8a ff ff       	call   c0100445 <__panic>
    assert((p2 = alloc_page()) != NULL);
c01079f1:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01079f8:	e8 a2 bd ff ff       	call   c010379f <alloc_pages>
c01079fd:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0107a00:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107a04:	75 24                	jne    c0107a2a <basic_check+0x3cc>
c0107a06:	c7 44 24 0c f8 aa 10 	movl   $0xc010aaf8,0xc(%esp)
c0107a0d:	c0 
c0107a0e:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107a15:	c0 
c0107a16:	c7 44 24 04 21 01 00 	movl   $0x121,0x4(%esp)
c0107a1d:	00 
c0107a1e:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107a25:	e8 1b 8a ff ff       	call   c0100445 <__panic>
    // 测试空闲页面是否不足
    assert(alloc_page() == NULL);
c0107a2a:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0107a31:	e8 69 bd ff ff       	call   c010379f <alloc_pages>
c0107a36:	85 c0                	test   %eax,%eax
c0107a38:	74 24                	je     c0107a5e <basic_check+0x400>
c0107a3a:	c7 44 24 0c e2 ab 10 	movl   $0xc010abe2,0xc(%esp)
c0107a41:	c0 
c0107a42:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107a49:	c0 
c0107a4a:	c7 44 24 04 23 01 00 	movl   $0x123,0x4(%esp)
c0107a51:	00 
c0107a52:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107a59:	e8 e7 89 ff ff       	call   c0100445 <__panic>
    // 释放 p0，并检查空闲列表
    free_page(p0);
c0107a5e:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107a65:	00 
c0107a66:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107a69:	89 04 24             	mov    %eax,(%esp)
c0107a6c:	e8 9d bd ff ff       	call   c010380e <free_pages>
c0107a71:	c7 45 d8 64 71 12 c0 	movl   $0xc0127164,-0x28(%ebp)
c0107a78:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0107a7b:	8b 40 04             	mov    0x4(%eax),%eax
c0107a7e:	39 45 d8             	cmp    %eax,-0x28(%ebp)
c0107a81:	0f 94 c0             	sete   %al
c0107a84:	0f b6 c0             	movzbl %al,%eax
    assert(!list_empty(&free_list));// 确保空闲列表不为空
c0107a87:	85 c0                	test   %eax,%eax
c0107a89:	74 24                	je     c0107aaf <basic_check+0x451>
c0107a8b:	c7 44 24 0c 04 ac 10 	movl   $0xc010ac04,0xc(%esp)
c0107a92:	c0 
c0107a93:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107a9a:	c0 
c0107a9b:	c7 44 24 04 26 01 00 	movl   $0x126,0x4(%esp)
c0107aa2:	00 
c0107aa3:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107aaa:	e8 96 89 ff ff       	call   c0100445 <__panic>

    struct Page *p;
    // 重新分配 p0，确保取回的是相同的页面
    assert((p = alloc_page()) == p0);
c0107aaf:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0107ab6:	e8 e4 bc ff ff       	call   c010379f <alloc_pages>
c0107abb:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0107abe:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107ac1:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0107ac4:	74 24                	je     c0107aea <basic_check+0x48c>
c0107ac6:	c7 44 24 0c 1c ac 10 	movl   $0xc010ac1c,0xc(%esp)
c0107acd:	c0 
c0107ace:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107ad5:	c0 
c0107ad6:	c7 44 24 04 2a 01 00 	movl   $0x12a,0x4(%esp)
c0107add:	00 
c0107ade:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107ae5:	e8 5b 89 ff ff       	call   c0100445 <__panic>
    assert(alloc_page() == NULL);// 确保没有更多的页面可分配
c0107aea:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0107af1:	e8 a9 bc ff ff       	call   c010379f <alloc_pages>
c0107af6:	85 c0                	test   %eax,%eax
c0107af8:	74 24                	je     c0107b1e <basic_check+0x4c0>
c0107afa:	c7 44 24 0c e2 ab 10 	movl   $0xc010abe2,0xc(%esp)
c0107b01:	c0 
c0107b02:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107b09:	c0 
c0107b0a:	c7 44 24 04 2b 01 00 	movl   $0x12b,0x4(%esp)
c0107b11:	00 
c0107b12:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107b19:	e8 27 89 ff ff       	call   c0100445 <__panic>

    assert(nr_free == 0);// 确保当前空闲页面数量为 0
c0107b1e:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c0107b23:	85 c0                	test   %eax,%eax
c0107b25:	74 24                	je     c0107b4b <basic_check+0x4ed>
c0107b27:	c7 44 24 0c 35 ac 10 	movl   $0xc010ac35,0xc(%esp)
c0107b2e:	c0 
c0107b2f:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107b36:	c0 
c0107b37:	c7 44 24 04 2d 01 00 	movl   $0x12d,0x4(%esp)
c0107b3e:	00 
c0107b3f:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107b46:	e8 fa 88 ff ff       	call   c0100445 <__panic>
    // 恢复之前的空闲页面链表和数量
    free_list = free_list_store;
c0107b4b:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0107b4e:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0107b51:	a3 64 71 12 c0       	mov    %eax,0xc0127164
c0107b56:	89 15 68 71 12 c0    	mov    %edx,0xc0127168
    nr_free = nr_free_store;
c0107b5c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107b5f:	a3 6c 71 12 c0       	mov    %eax,0xc012716c
    // 释放最后的页面
    free_page(p);
c0107b64:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107b6b:	00 
c0107b6c:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107b6f:	89 04 24             	mov    %eax,(%esp)
c0107b72:	e8 97 bc ff ff       	call   c010380e <free_pages>
    free_page(p1);
c0107b77:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107b7e:	00 
c0107b7f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107b82:	89 04 24             	mov    %eax,(%esp)
c0107b85:	e8 84 bc ff ff       	call   c010380e <free_pages>
    free_page(p2);
c0107b8a:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107b91:	00 
c0107b92:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107b95:	89 04 24             	mov    %eax,(%esp)
c0107b98:	e8 71 bc ff ff       	call   c010380e <free_pages>
}
c0107b9d:	90                   	nop
c0107b9e:	c9                   	leave  
c0107b9f:	c3                   	ret    

c0107ba0 <default_check>:

// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) 
// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions!
static void
default_check(void) {
c0107ba0:	f3 0f 1e fb          	endbr32 
c0107ba4:	55                   	push   %ebp
c0107ba5:	89 e5                	mov    %esp,%ebp
c0107ba7:	81 ec 98 00 00 00    	sub    $0x98,%esp
    int count = 0, total = 0;
c0107bad:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0107bb4:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    list_entry_t *le = &free_list;
c0107bbb:	c7 45 ec 64 71 12 c0 	movl   $0xc0127164,-0x14(%ebp)
    // 遍历空闲列表，计算空闲页面的数量和总属性值
    while ((le = list_next(le)) != &free_list) {
c0107bc2:	eb 6a                	jmp    c0107c2e <default_check+0x8e>
        struct Page *p = le2page(le, page_link);
c0107bc4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107bc7:	83 e8 0c             	sub    $0xc,%eax
c0107bca:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        assert(PageProperty(p));// 确保每个页面的属性是有效的
c0107bcd:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107bd0:	83 c0 04             	add    $0x4,%eax
c0107bd3:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c0107bda:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0107bdd:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0107be0:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0107be3:	0f a3 10             	bt     %edx,(%eax)
c0107be6:	19 c0                	sbb    %eax,%eax
c0107be8:	89 45 c8             	mov    %eax,-0x38(%ebp)
    return oldbit != 0;
c0107beb:	83 7d c8 00          	cmpl   $0x0,-0x38(%ebp)
c0107bef:	0f 95 c0             	setne  %al
c0107bf2:	0f b6 c0             	movzbl %al,%eax
c0107bf5:	85 c0                	test   %eax,%eax
c0107bf7:	75 24                	jne    c0107c1d <default_check+0x7d>
c0107bf9:	c7 44 24 0c 42 ac 10 	movl   $0xc010ac42,0xc(%esp)
c0107c00:	c0 
c0107c01:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107c08:	c0 
c0107c09:	c7 44 24 04 40 01 00 	movl   $0x140,0x4(%esp)
c0107c10:	00 
c0107c11:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107c18:	e8 28 88 ff ff       	call   c0100445 <__panic>
        count ++, total += p->property;// 累加页面属性
c0107c1d:	ff 45 f4             	incl   -0xc(%ebp)
c0107c20:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107c23:	8b 50 08             	mov    0x8(%eax),%edx
c0107c26:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107c29:	01 d0                	add    %edx,%eax
c0107c2b:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0107c2e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107c31:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    return listelm->next;
c0107c34:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0107c37:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c0107c3a:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0107c3d:	81 7d ec 64 71 12 c0 	cmpl   $0xc0127164,-0x14(%ebp)
c0107c44:	0f 85 7a ff ff ff    	jne    c0107bc4 <default_check+0x24>
    }
    // 确保总属性值与空闲页面数量匹配
    assert(total == nr_free_pages());
c0107c4a:	e8 f6 bb ff ff       	call   c0103845 <nr_free_pages>
c0107c4f:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0107c52:	39 d0                	cmp    %edx,%eax
c0107c54:	74 24                	je     c0107c7a <default_check+0xda>
c0107c56:	c7 44 24 0c 52 ac 10 	movl   $0xc010ac52,0xc(%esp)
c0107c5d:	c0 
c0107c5e:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107c65:	c0 
c0107c66:	c7 44 24 04 44 01 00 	movl   $0x144,0x4(%esp)
c0107c6d:	00 
c0107c6e:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107c75:	e8 cb 87 ff ff       	call   c0100445 <__panic>
    // 调用 basic_check 以验证基本的内存管理功能
    basic_check();
c0107c7a:	e8 df f9 ff ff       	call   c010765e <basic_check>
    // 分配 5 个页面
    struct Page *p0 = alloc_pages(5), *p1, *p2;
c0107c7f:	c7 04 24 05 00 00 00 	movl   $0x5,(%esp)
c0107c86:	e8 14 bb ff ff       	call   c010379f <alloc_pages>
c0107c8b:	89 45 e8             	mov    %eax,-0x18(%ebp)
    assert(p0 != NULL);// 确保成功分配
c0107c8e:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0107c92:	75 24                	jne    c0107cb8 <default_check+0x118>
c0107c94:	c7 44 24 0c 6b ac 10 	movl   $0xc010ac6b,0xc(%esp)
c0107c9b:	c0 
c0107c9c:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107ca3:	c0 
c0107ca4:	c7 44 24 04 49 01 00 	movl   $0x149,0x4(%esp)
c0107cab:	00 
c0107cac:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107cb3:	e8 8d 87 ff ff       	call   c0100445 <__panic>
    assert(!PageProperty(p0));// 确保分配的页面不带属性
c0107cb8:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107cbb:	83 c0 04             	add    $0x4,%eax
c0107cbe:	c7 45 c0 01 00 00 00 	movl   $0x1,-0x40(%ebp)
c0107cc5:	89 45 bc             	mov    %eax,-0x44(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0107cc8:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0107ccb:	8b 55 c0             	mov    -0x40(%ebp),%edx
c0107cce:	0f a3 10             	bt     %edx,(%eax)
c0107cd1:	19 c0                	sbb    %eax,%eax
c0107cd3:	89 45 b8             	mov    %eax,-0x48(%ebp)
    return oldbit != 0;
c0107cd6:	83 7d b8 00          	cmpl   $0x0,-0x48(%ebp)
c0107cda:	0f 95 c0             	setne  %al
c0107cdd:	0f b6 c0             	movzbl %al,%eax
c0107ce0:	85 c0                	test   %eax,%eax
c0107ce2:	74 24                	je     c0107d08 <default_check+0x168>
c0107ce4:	c7 44 24 0c 76 ac 10 	movl   $0xc010ac76,0xc(%esp)
c0107ceb:	c0 
c0107cec:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107cf3:	c0 
c0107cf4:	c7 44 24 04 4a 01 00 	movl   $0x14a,0x4(%esp)
c0107cfb:	00 
c0107cfc:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107d03:	e8 3d 87 ff ff       	call   c0100445 <__panic>
     // 初始化并检查空闲列表
    list_entry_t free_list_store = free_list;
c0107d08:	a1 64 71 12 c0       	mov    0xc0127164,%eax
c0107d0d:	8b 15 68 71 12 c0    	mov    0xc0127168,%edx
c0107d13:	89 45 80             	mov    %eax,-0x80(%ebp)
c0107d16:	89 55 84             	mov    %edx,-0x7c(%ebp)
c0107d19:	c7 45 b0 64 71 12 c0 	movl   $0xc0127164,-0x50(%ebp)
    elm->prev = elm->next = elm;
c0107d20:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0107d23:	8b 55 b0             	mov    -0x50(%ebp),%edx
c0107d26:	89 50 04             	mov    %edx,0x4(%eax)
c0107d29:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0107d2c:	8b 50 04             	mov    0x4(%eax),%edx
c0107d2f:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0107d32:	89 10                	mov    %edx,(%eax)
}
c0107d34:	90                   	nop
c0107d35:	c7 45 b4 64 71 12 c0 	movl   $0xc0127164,-0x4c(%ebp)
    return list->next == list;
c0107d3c:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0107d3f:	8b 40 04             	mov    0x4(%eax),%eax
c0107d42:	39 45 b4             	cmp    %eax,-0x4c(%ebp)
c0107d45:	0f 94 c0             	sete   %al
c0107d48:	0f b6 c0             	movzbl %al,%eax
    list_init(&free_list);
    assert(list_empty(&free_list));// 确保空闲列表为空
c0107d4b:	85 c0                	test   %eax,%eax
c0107d4d:	75 24                	jne    c0107d73 <default_check+0x1d3>
c0107d4f:	c7 44 24 0c cb ab 10 	movl   $0xc010abcb,0xc(%esp)
c0107d56:	c0 
c0107d57:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107d5e:	c0 
c0107d5f:	c7 44 24 04 4e 01 00 	movl   $0x14e,0x4(%esp)
c0107d66:	00 
c0107d67:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107d6e:	e8 d2 86 ff ff       	call   c0100445 <__panic>
    assert(alloc_page() == NULL);// 确保没有页面可分配
c0107d73:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0107d7a:	e8 20 ba ff ff       	call   c010379f <alloc_pages>
c0107d7f:	85 c0                	test   %eax,%eax
c0107d81:	74 24                	je     c0107da7 <default_check+0x207>
c0107d83:	c7 44 24 0c e2 ab 10 	movl   $0xc010abe2,0xc(%esp)
c0107d8a:	c0 
c0107d8b:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107d92:	c0 
c0107d93:	c7 44 24 04 4f 01 00 	movl   $0x14f,0x4(%esp)
c0107d9a:	00 
c0107d9b:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107da2:	e8 9e 86 ff ff       	call   c0100445 <__panic>

    unsigned int nr_free_store = nr_free;// 保存当前空闲页数
c0107da7:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c0107dac:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    nr_free = 0;// 将空闲页数设为 0
c0107daf:	c7 05 6c 71 12 c0 00 	movl   $0x0,0xc012716c
c0107db6:	00 00 00 
    // 释放 3 个页面并确保分配页面时没有足够的空闲页
    free_pages(p0 + 2, 3);
c0107db9:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107dbc:	83 c0 40             	add    $0x40,%eax
c0107dbf:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%esp)
c0107dc6:	00 
c0107dc7:	89 04 24             	mov    %eax,(%esp)
c0107dca:	e8 3f ba ff ff       	call   c010380e <free_pages>
    assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面
c0107dcf:	c7 04 24 04 00 00 00 	movl   $0x4,(%esp)
c0107dd6:	e8 c4 b9 ff ff       	call   c010379f <alloc_pages>
c0107ddb:	85 c0                	test   %eax,%eax
c0107ddd:	74 24                	je     c0107e03 <default_check+0x263>
c0107ddf:	c7 44 24 0c 88 ac 10 	movl   $0xc010ac88,0xc(%esp)
c0107de6:	c0 
c0107de7:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107dee:	c0 
c0107def:	c7 44 24 04 55 01 00 	movl   $0x155,0x4(%esp)
c0107df6:	00 
c0107df7:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107dfe:	e8 42 86 ff ff       	call   c0100445 <__panic>
    assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性
c0107e03:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107e06:	83 c0 40             	add    $0x40,%eax
c0107e09:	83 c0 04             	add    $0x4,%eax
c0107e0c:	c7 45 ac 01 00 00 00 	movl   $0x1,-0x54(%ebp)
c0107e13:	89 45 a8             	mov    %eax,-0x58(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0107e16:	8b 45 a8             	mov    -0x58(%ebp),%eax
c0107e19:	8b 55 ac             	mov    -0x54(%ebp),%edx
c0107e1c:	0f a3 10             	bt     %edx,(%eax)
c0107e1f:	19 c0                	sbb    %eax,%eax
c0107e21:	89 45 a4             	mov    %eax,-0x5c(%ebp)
    return oldbit != 0;
c0107e24:	83 7d a4 00          	cmpl   $0x0,-0x5c(%ebp)
c0107e28:	0f 95 c0             	setne  %al
c0107e2b:	0f b6 c0             	movzbl %al,%eax
c0107e2e:	85 c0                	test   %eax,%eax
c0107e30:	74 0e                	je     c0107e40 <default_check+0x2a0>
c0107e32:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107e35:	83 c0 40             	add    $0x40,%eax
c0107e38:	8b 40 08             	mov    0x8(%eax),%eax
c0107e3b:	83 f8 03             	cmp    $0x3,%eax
c0107e3e:	74 24                	je     c0107e64 <default_check+0x2c4>
c0107e40:	c7 44 24 0c a0 ac 10 	movl   $0xc010aca0,0xc(%esp)
c0107e47:	c0 
c0107e48:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107e4f:	c0 
c0107e50:	c7 44 24 04 56 01 00 	movl   $0x156,0x4(%esp)
c0107e57:	00 
c0107e58:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107e5f:	e8 e1 85 ff ff       	call   c0100445 <__panic>
    assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面
c0107e64:	c7 04 24 03 00 00 00 	movl   $0x3,(%esp)
c0107e6b:	e8 2f b9 ff ff       	call   c010379f <alloc_pages>
c0107e70:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0107e73:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c0107e77:	75 24                	jne    c0107e9d <default_check+0x2fd>
c0107e79:	c7 44 24 0c cc ac 10 	movl   $0xc010accc,0xc(%esp)
c0107e80:	c0 
c0107e81:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107e88:	c0 
c0107e89:	c7 44 24 04 57 01 00 	movl   $0x157,0x4(%esp)
c0107e90:	00 
c0107e91:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107e98:	e8 a8 85 ff ff       	call   c0100445 <__panic>
    assert(alloc_page() == NULL);// 确保没有页面可分配
c0107e9d:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0107ea4:	e8 f6 b8 ff ff       	call   c010379f <alloc_pages>
c0107ea9:	85 c0                	test   %eax,%eax
c0107eab:	74 24                	je     c0107ed1 <default_check+0x331>
c0107ead:	c7 44 24 0c e2 ab 10 	movl   $0xc010abe2,0xc(%esp)
c0107eb4:	c0 
c0107eb5:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107ebc:	c0 
c0107ebd:	c7 44 24 04 58 01 00 	movl   $0x158,0x4(%esp)
c0107ec4:	00 
c0107ec5:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107ecc:	e8 74 85 ff ff       	call   c0100445 <__panic>
    assert(p0 + 2 == p1);// 确保分配的页面是释放的页面
c0107ed1:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107ed4:	83 c0 40             	add    $0x40,%eax
c0107ed7:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c0107eda:	74 24                	je     c0107f00 <default_check+0x360>
c0107edc:	c7 44 24 0c ea ac 10 	movl   $0xc010acea,0xc(%esp)
c0107ee3:	c0 
c0107ee4:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107eeb:	c0 
c0107eec:	c7 44 24 04 59 01 00 	movl   $0x159,0x4(%esp)
c0107ef3:	00 
c0107ef4:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107efb:	e8 45 85 ff ff       	call   c0100445 <__panic>

    p2 = p0 + 1;// 设置 p2 为 p0 的下一个页面
c0107f00:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107f03:	83 c0 20             	add    $0x20,%eax
c0107f06:	89 45 dc             	mov    %eax,-0x24(%ebp)
    free_page(p0);// 释放 p0 页面
c0107f09:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0107f10:	00 
c0107f11:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107f14:	89 04 24             	mov    %eax,(%esp)
c0107f17:	e8 f2 b8 ff ff       	call   c010380e <free_pages>
    free_pages(p1, 3);// 释放 p1 指向的页面
c0107f1c:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%esp)
c0107f23:	00 
c0107f24:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107f27:	89 04 24             	mov    %eax,(%esp)
c0107f2a:	e8 df b8 ff ff       	call   c010380e <free_pages>
    assert(PageProperty(p0) && p0->property == 1);// 检查 p0 属性
c0107f2f:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107f32:	83 c0 04             	add    $0x4,%eax
c0107f35:	c7 45 a0 01 00 00 00 	movl   $0x1,-0x60(%ebp)
c0107f3c:	89 45 9c             	mov    %eax,-0x64(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0107f3f:	8b 45 9c             	mov    -0x64(%ebp),%eax
c0107f42:	8b 55 a0             	mov    -0x60(%ebp),%edx
c0107f45:	0f a3 10             	bt     %edx,(%eax)
c0107f48:	19 c0                	sbb    %eax,%eax
c0107f4a:	89 45 98             	mov    %eax,-0x68(%ebp)
    return oldbit != 0;
c0107f4d:	83 7d 98 00          	cmpl   $0x0,-0x68(%ebp)
c0107f51:	0f 95 c0             	setne  %al
c0107f54:	0f b6 c0             	movzbl %al,%eax
c0107f57:	85 c0                	test   %eax,%eax
c0107f59:	74 0b                	je     c0107f66 <default_check+0x3c6>
c0107f5b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107f5e:	8b 40 08             	mov    0x8(%eax),%eax
c0107f61:	83 f8 01             	cmp    $0x1,%eax
c0107f64:	74 24                	je     c0107f8a <default_check+0x3ea>
c0107f66:	c7 44 24 0c f8 ac 10 	movl   $0xc010acf8,0xc(%esp)
c0107f6d:	c0 
c0107f6e:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107f75:	c0 
c0107f76:	c7 44 24 04 5e 01 00 	movl   $0x15e,0x4(%esp)
c0107f7d:	00 
c0107f7e:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107f85:	e8 bb 84 ff ff       	call   c0100445 <__panic>
    assert(PageProperty(p1) && p1->property == 3);// 检查 p1 属性
c0107f8a:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107f8d:	83 c0 04             	add    $0x4,%eax
c0107f90:	c7 45 94 01 00 00 00 	movl   $0x1,-0x6c(%ebp)
c0107f97:	89 45 90             	mov    %eax,-0x70(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0107f9a:	8b 45 90             	mov    -0x70(%ebp),%eax
c0107f9d:	8b 55 94             	mov    -0x6c(%ebp),%edx
c0107fa0:	0f a3 10             	bt     %edx,(%eax)
c0107fa3:	19 c0                	sbb    %eax,%eax
c0107fa5:	89 45 8c             	mov    %eax,-0x74(%ebp)
    return oldbit != 0;
c0107fa8:	83 7d 8c 00          	cmpl   $0x0,-0x74(%ebp)
c0107fac:	0f 95 c0             	setne  %al
c0107faf:	0f b6 c0             	movzbl %al,%eax
c0107fb2:	85 c0                	test   %eax,%eax
c0107fb4:	74 0b                	je     c0107fc1 <default_check+0x421>
c0107fb6:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107fb9:	8b 40 08             	mov    0x8(%eax),%eax
c0107fbc:	83 f8 03             	cmp    $0x3,%eax
c0107fbf:	74 24                	je     c0107fe5 <default_check+0x445>
c0107fc1:	c7 44 24 0c 20 ad 10 	movl   $0xc010ad20,0xc(%esp)
c0107fc8:	c0 
c0107fc9:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c0107fd0:	c0 
c0107fd1:	c7 44 24 04 5f 01 00 	movl   $0x15f,0x4(%esp)
c0107fd8:	00 
c0107fd9:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0107fe0:	e8 60 84 ff ff       	call   c0100445 <__panic>
    // 确保重分配的页面是之前释放的页面
    assert((p0 = alloc_page()) == p2 - 1);
c0107fe5:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0107fec:	e8 ae b7 ff ff       	call   c010379f <alloc_pages>
c0107ff1:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0107ff4:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0107ff7:	83 e8 20             	sub    $0x20,%eax
c0107ffa:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c0107ffd:	74 24                	je     c0108023 <default_check+0x483>
c0107fff:	c7 44 24 0c 46 ad 10 	movl   $0xc010ad46,0xc(%esp)
c0108006:	c0 
c0108007:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c010800e:	c0 
c010800f:	c7 44 24 04 61 01 00 	movl   $0x161,0x4(%esp)
c0108016:	00 
c0108017:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c010801e:	e8 22 84 ff ff       	call   c0100445 <__panic>
    free_page(p0);// 释放分配的页面
c0108023:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010802a:	00 
c010802b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010802e:	89 04 24             	mov    %eax,(%esp)
c0108031:	e8 d8 b7 ff ff       	call   c010380e <free_pages>
    assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查
c0108036:	c7 04 24 02 00 00 00 	movl   $0x2,(%esp)
c010803d:	e8 5d b7 ff ff       	call   c010379f <alloc_pages>
c0108042:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0108045:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108048:	83 c0 20             	add    $0x20,%eax
c010804b:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c010804e:	74 24                	je     c0108074 <default_check+0x4d4>
c0108050:	c7 44 24 0c 64 ad 10 	movl   $0xc010ad64,0xc(%esp)
c0108057:	c0 
c0108058:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c010805f:	c0 
c0108060:	c7 44 24 04 63 01 00 	movl   $0x163,0x4(%esp)
c0108067:	00 
c0108068:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c010806f:	e8 d1 83 ff ff       	call   c0100445 <__panic>
    // 释放页面并检查空闲状态
    free_pages(p0, 2);
c0108074:	c7 44 24 04 02 00 00 	movl   $0x2,0x4(%esp)
c010807b:	00 
c010807c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010807f:	89 04 24             	mov    %eax,(%esp)
c0108082:	e8 87 b7 ff ff       	call   c010380e <free_pages>
    free_page(p2);
c0108087:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010808e:	00 
c010808f:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108092:	89 04 24             	mov    %eax,(%esp)
c0108095:	e8 74 b7 ff ff       	call   c010380e <free_pages>
    // 再次分配 5 个页面
    assert((p0 = alloc_pages(5)) != NULL);
c010809a:	c7 04 24 05 00 00 00 	movl   $0x5,(%esp)
c01080a1:	e8 f9 b6 ff ff       	call   c010379f <alloc_pages>
c01080a6:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01080a9:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c01080ad:	75 24                	jne    c01080d3 <default_check+0x533>
c01080af:	c7 44 24 0c 84 ad 10 	movl   $0xc010ad84,0xc(%esp)
c01080b6:	c0 
c01080b7:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01080be:	c0 
c01080bf:	c7 44 24 04 68 01 00 	movl   $0x168,0x4(%esp)
c01080c6:	00 
c01080c7:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01080ce:	e8 72 83 ff ff       	call   c0100445 <__panic>
    assert(alloc_page() == NULL);// 确保没有额外页面可分配
c01080d3:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01080da:	e8 c0 b6 ff ff       	call   c010379f <alloc_pages>
c01080df:	85 c0                	test   %eax,%eax
c01080e1:	74 24                	je     c0108107 <default_check+0x567>
c01080e3:	c7 44 24 0c e2 ab 10 	movl   $0xc010abe2,0xc(%esp)
c01080ea:	c0 
c01080eb:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01080f2:	c0 
c01080f3:	c7 44 24 04 69 01 00 	movl   $0x169,0x4(%esp)
c01080fa:	00 
c01080fb:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c0108102:	e8 3e 83 ff ff       	call   c0100445 <__panic>

    assert(nr_free == 0);// 确保空闲页数为 0
c0108107:	a1 6c 71 12 c0       	mov    0xc012716c,%eax
c010810c:	85 c0                	test   %eax,%eax
c010810e:	74 24                	je     c0108134 <default_check+0x594>
c0108110:	c7 44 24 0c 35 ac 10 	movl   $0xc010ac35,0xc(%esp)
c0108117:	c0 
c0108118:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c010811f:	c0 
c0108120:	c7 44 24 04 6b 01 00 	movl   $0x16b,0x4(%esp)
c0108127:	00 
c0108128:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c010812f:	e8 11 83 ff ff       	call   c0100445 <__panic>
    nr_free = nr_free_store;// 恢复空闲页数
c0108134:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108137:	a3 6c 71 12 c0       	mov    %eax,0xc012716c
    // 恢复空闲列表状态
    free_list = free_list_store;
c010813c:	8b 45 80             	mov    -0x80(%ebp),%eax
c010813f:	8b 55 84             	mov    -0x7c(%ebp),%edx
c0108142:	a3 64 71 12 c0       	mov    %eax,0xc0127164
c0108147:	89 15 68 71 12 c0    	mov    %edx,0xc0127168
    free_pages(p0, 5);// 释放所有分配的页面
c010814d:	c7 44 24 04 05 00 00 	movl   $0x5,0x4(%esp)
c0108154:	00 
c0108155:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108158:	89 04 24             	mov    %eax,(%esp)
c010815b:	e8 ae b6 ff ff       	call   c010380e <free_pages>
    // 验证空闲列表的一致性
    le = &free_list;
c0108160:	c7 45 ec 64 71 12 c0 	movl   $0xc0127164,-0x14(%ebp)
    while ((le = list_next(le)) != &free_list) {
c0108167:	eb 1c                	jmp    c0108185 <default_check+0x5e5>
        struct Page *p = le2page(le, page_link);
c0108169:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010816c:	83 e8 0c             	sub    $0xc,%eax
c010816f:	89 45 d8             	mov    %eax,-0x28(%ebp)
        count --, total -= p->property;
c0108172:	ff 4d f4             	decl   -0xc(%ebp)
c0108175:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0108178:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010817b:	8b 40 08             	mov    0x8(%eax),%eax
c010817e:	29 c2                	sub    %eax,%edx
c0108180:	89 d0                	mov    %edx,%eax
c0108182:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108185:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108188:	89 45 88             	mov    %eax,-0x78(%ebp)
    return listelm->next;
c010818b:	8b 45 88             	mov    -0x78(%ebp),%eax
c010818e:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c0108191:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0108194:	81 7d ec 64 71 12 c0 	cmpl   $0xc0127164,-0x14(%ebp)
c010819b:	75 cc                	jne    c0108169 <default_check+0x5c9>
    }
    assert(count == 0);// 确保所有页面都已处理
c010819d:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01081a1:	74 24                	je     c01081c7 <default_check+0x627>
c01081a3:	c7 44 24 0c a2 ad 10 	movl   $0xc010ada2,0xc(%esp)
c01081aa:	c0 
c01081ab:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01081b2:	c0 
c01081b3:	c7 44 24 04 76 01 00 	movl   $0x176,0x4(%esp)
c01081ba:	00 
c01081bb:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01081c2:	e8 7e 82 ff ff       	call   c0100445 <__panic>
    assert(total == 0);// 确保总属性值为 0
c01081c7:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01081cb:	74 24                	je     c01081f1 <default_check+0x651>
c01081cd:	c7 44 24 0c ad ad 10 	movl   $0xc010adad,0xc(%esp)
c01081d4:	c0 
c01081d5:	c7 44 24 08 42 aa 10 	movl   $0xc010aa42,0x8(%esp)
c01081dc:	c0 
c01081dd:	c7 44 24 04 77 01 00 	movl   $0x177,0x4(%esp)
c01081e4:	00 
c01081e5:	c7 04 24 57 aa 10 c0 	movl   $0xc010aa57,(%esp)
c01081ec:	e8 54 82 ff ff       	call   c0100445 <__panic>
}
c01081f1:	90                   	nop
c01081f2:	c9                   	leave  
c01081f3:	c3                   	ret    

c01081f4 <page2ppn>:
page2ppn(struct Page *page) {
c01081f4:	55                   	push   %ebp
c01081f5:	89 e5                	mov    %esp,%ebp
    return page - pages;
c01081f7:	a1 78 70 12 c0       	mov    0xc0127078,%eax
c01081fc:	8b 55 08             	mov    0x8(%ebp),%edx
c01081ff:	29 c2                	sub    %eax,%edx
c0108201:	89 d0                	mov    %edx,%eax
c0108203:	c1 f8 05             	sar    $0x5,%eax
}
c0108206:	5d                   	pop    %ebp
c0108207:	c3                   	ret    

c0108208 <page2pa>:
page2pa(struct Page *page) {
c0108208:	55                   	push   %ebp
c0108209:	89 e5                	mov    %esp,%ebp
c010820b:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c010820e:	8b 45 08             	mov    0x8(%ebp),%eax
c0108211:	89 04 24             	mov    %eax,(%esp)
c0108214:	e8 db ff ff ff       	call   c01081f4 <page2ppn>
c0108219:	c1 e0 0c             	shl    $0xc,%eax
}
c010821c:	c9                   	leave  
c010821d:	c3                   	ret    

c010821e <page2kva>:
page2kva(struct Page *page) {
c010821e:	55                   	push   %ebp
c010821f:	89 e5                	mov    %esp,%ebp
c0108221:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c0108224:	8b 45 08             	mov    0x8(%ebp),%eax
c0108227:	89 04 24             	mov    %eax,(%esp)
c010822a:	e8 d9 ff ff ff       	call   c0108208 <page2pa>
c010822f:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108232:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108235:	c1 e8 0c             	shr    $0xc,%eax
c0108238:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010823b:	a1 80 6f 12 c0       	mov    0xc0126f80,%eax
c0108240:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0108243:	72 23                	jb     c0108268 <page2kva+0x4a>
c0108245:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108248:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010824c:	c7 44 24 08 e8 ad 10 	movl   $0xc010ade8,0x8(%esp)
c0108253:	c0 
c0108254:	c7 44 24 04 62 00 00 	movl   $0x62,0x4(%esp)
c010825b:	00 
c010825c:	c7 04 24 0b ae 10 c0 	movl   $0xc010ae0b,(%esp)
c0108263:	e8 dd 81 ff ff       	call   c0100445 <__panic>
c0108268:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010826b:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c0108270:	c9                   	leave  
c0108271:	c3                   	ret    

c0108272 <swapfs_init>:
 *    并提示交换文件系统不可用，这确保了系统在不合适的配置下不会继续运行，避免了潜在的错误。
 * 3. 计算并设置交换分区上可用于交换的最大偏移量（max_swap_offset），
 *    这是通过将交换设备的大小除以每个页面对应的扇区数得到的，它限制了交换分区的使用范围。
 */
void
swapfs_init(void) {
c0108272:	f3 0f 1e fb          	endbr32 
c0108276:	55                   	push   %ebp
c0108277:	89 e5                	mov    %esp,%ebp
c0108279:	83 ec 18             	sub    $0x18,%esp
    // 确保页面大小是扇区大小的倍数，以保证数据对齐
    static_assert((PGSIZE % SECTSIZE) == 0);

    // 检查交换设备是否有效，确保交换功能可以使用
    if (!ide_device_valid(SWAP_DEV_NO)) {
c010827c:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0108283:	e8 37 8e ff ff       	call   c01010bf <ide_device_valid>
c0108288:	85 c0                	test   %eax,%eax
c010828a:	75 1c                	jne    c01082a8 <swapfs_init+0x36>
        panic("swap fs isn't available.\n");
c010828c:	c7 44 24 08 19 ae 10 	movl   $0xc010ae19,0x8(%esp)
c0108293:	c0 
c0108294:	c7 44 24 04 1a 00 00 	movl   $0x1a,0x4(%esp)
c010829b:	00 
c010829c:	c7 04 24 33 ae 10 c0 	movl   $0xc010ae33,(%esp)
c01082a3:	e8 9d 81 ff ff       	call   c0100445 <__panic>
    }
    // 计算交换分区上可用于交换的最大偏移量
    max_swap_offset = ide_device_size(SWAP_DEV_NO) / (PGSIZE / SECTSIZE);
c01082a8:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01082af:	e8 4d 8e ff ff       	call   c0101101 <ide_device_size>
c01082b4:	c1 e8 03             	shr    $0x3,%eax
c01082b7:	a3 3c 71 12 c0       	mov    %eax,0xc012713c
}
c01082bc:	90                   	nop
c01082bd:	c9                   	leave  
c01082be:	c3                   	ret    

c01082bf <swapfs_read>:
//entry：表示要读取的交换条目。page：指向要填充的内存页的指针。
//函数返回 ide_read_secs 的结果，表示读取操作是否成功
//计算交换条目的偏移量 swap_offset(entry)。
//使用 ide_read_secs 函数从交换设备 SWAP_DEV_NO 中读取指定数量的扇区（PAGE_NSECT）到内存页 page2kva(page) 中。
int
swapfs_read(swap_entry_t entry, struct Page *page) {
c01082bf:	f3 0f 1e fb          	endbr32 
c01082c3:	55                   	push   %ebp
c01082c4:	89 e5                	mov    %esp,%ebp
c01082c6:	83 ec 28             	sub    $0x28,%esp
    return ide_read_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT);
c01082c9:	8b 45 0c             	mov    0xc(%ebp),%eax
c01082cc:	89 04 24             	mov    %eax,(%esp)
c01082cf:	e8 4a ff ff ff       	call   c010821e <page2kva>
c01082d4:	8b 55 08             	mov    0x8(%ebp),%edx
c01082d7:	c1 ea 08             	shr    $0x8,%edx
c01082da:	89 55 f4             	mov    %edx,-0xc(%ebp)
c01082dd:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01082e1:	74 0b                	je     c01082ee <swapfs_read+0x2f>
c01082e3:	8b 15 3c 71 12 c0    	mov    0xc012713c,%edx
c01082e9:	39 55 f4             	cmp    %edx,-0xc(%ebp)
c01082ec:	72 23                	jb     c0108311 <swapfs_read+0x52>
c01082ee:	8b 45 08             	mov    0x8(%ebp),%eax
c01082f1:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01082f5:	c7 44 24 08 44 ae 10 	movl   $0xc010ae44,0x8(%esp)
c01082fc:	c0 
c01082fd:	c7 44 24 04 26 00 00 	movl   $0x26,0x4(%esp)
c0108304:	00 
c0108305:	c7 04 24 33 ae 10 c0 	movl   $0xc010ae33,(%esp)
c010830c:	e8 34 81 ff ff       	call   c0100445 <__panic>
c0108311:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108314:	c1 e2 03             	shl    $0x3,%edx
c0108317:	c7 44 24 0c 08 00 00 	movl   $0x8,0xc(%esp)
c010831e:	00 
c010831f:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108323:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108327:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c010832e:	e8 0d 8e ff ff       	call   c0101140 <ide_read_secs>
}
c0108333:	c9                   	leave  
c0108334:	c3                   	ret    

c0108335 <swapfs_write>:

int
swapfs_write(swap_entry_t entry, struct Page *page) {
c0108335:	f3 0f 1e fb          	endbr32 
c0108339:	55                   	push   %ebp
c010833a:	89 e5                	mov    %esp,%ebp
c010833c:	83 ec 28             	sub    $0x28,%esp
    return ide_write_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT);
c010833f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108342:	89 04 24             	mov    %eax,(%esp)
c0108345:	e8 d4 fe ff ff       	call   c010821e <page2kva>
c010834a:	8b 55 08             	mov    0x8(%ebp),%edx
c010834d:	c1 ea 08             	shr    $0x8,%edx
c0108350:	89 55 f4             	mov    %edx,-0xc(%ebp)
c0108353:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0108357:	74 0b                	je     c0108364 <swapfs_write+0x2f>
c0108359:	8b 15 3c 71 12 c0    	mov    0xc012713c,%edx
c010835f:	39 55 f4             	cmp    %edx,-0xc(%ebp)
c0108362:	72 23                	jb     c0108387 <swapfs_write+0x52>
c0108364:	8b 45 08             	mov    0x8(%ebp),%eax
c0108367:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010836b:	c7 44 24 08 44 ae 10 	movl   $0xc010ae44,0x8(%esp)
c0108372:	c0 
c0108373:	c7 44 24 04 2b 00 00 	movl   $0x2b,0x4(%esp)
c010837a:	00 
c010837b:	c7 04 24 33 ae 10 c0 	movl   $0xc010ae33,(%esp)
c0108382:	e8 be 80 ff ff       	call   c0100445 <__panic>
c0108387:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010838a:	c1 e2 03             	shl    $0x3,%edx
c010838d:	c7 44 24 0c 08 00 00 	movl   $0x8,0xc(%esp)
c0108394:	00 
c0108395:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108399:	89 54 24 04          	mov    %edx,0x4(%esp)
c010839d:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01083a4:	e8 dc 8f ff ff       	call   c0101385 <ide_write_secs>
}
c01083a9:	c9                   	leave  
c01083aa:	c3                   	ret    

c01083ab <strlen>:
 * @s:      the input string
 *
 * The strlen() function returns the length of string @s.
 * */
size_t
strlen(const char *s) {
c01083ab:	f3 0f 1e fb          	endbr32 
c01083af:	55                   	push   %ebp
c01083b0:	89 e5                	mov    %esp,%ebp
c01083b2:	83 ec 10             	sub    $0x10,%esp
    size_t cnt = 0;
c01083b5:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    while (*s ++ != '\0') {
c01083bc:	eb 03                	jmp    c01083c1 <strlen+0x16>
        cnt ++;
c01083be:	ff 45 fc             	incl   -0x4(%ebp)
    while (*s ++ != '\0') {
c01083c1:	8b 45 08             	mov    0x8(%ebp),%eax
c01083c4:	8d 50 01             	lea    0x1(%eax),%edx
c01083c7:	89 55 08             	mov    %edx,0x8(%ebp)
c01083ca:	0f b6 00             	movzbl (%eax),%eax
c01083cd:	84 c0                	test   %al,%al
c01083cf:	75 ed                	jne    c01083be <strlen+0x13>
    }
    return cnt;
c01083d1:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c01083d4:	c9                   	leave  
c01083d5:	c3                   	ret    

c01083d6 <strnlen>:
 * The return value is strlen(s), if that is less than @len, or
 * @len if there is no '\0' character among the first @len characters
 * pointed by @s.
 * */
size_t
strnlen(const char *s, size_t len) {
c01083d6:	f3 0f 1e fb          	endbr32 
c01083da:	55                   	push   %ebp
c01083db:	89 e5                	mov    %esp,%ebp
c01083dd:	83 ec 10             	sub    $0x10,%esp
    size_t cnt = 0;
c01083e0:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    while (cnt < len && *s ++ != '\0') {
c01083e7:	eb 03                	jmp    c01083ec <strnlen+0x16>
        cnt ++;
c01083e9:	ff 45 fc             	incl   -0x4(%ebp)
    while (cnt < len && *s ++ != '\0') {
c01083ec:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01083ef:	3b 45 0c             	cmp    0xc(%ebp),%eax
c01083f2:	73 10                	jae    c0108404 <strnlen+0x2e>
c01083f4:	8b 45 08             	mov    0x8(%ebp),%eax
c01083f7:	8d 50 01             	lea    0x1(%eax),%edx
c01083fa:	89 55 08             	mov    %edx,0x8(%ebp)
c01083fd:	0f b6 00             	movzbl (%eax),%eax
c0108400:	84 c0                	test   %al,%al
c0108402:	75 e5                	jne    c01083e9 <strnlen+0x13>
    }
    return cnt;
c0108404:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0108407:	c9                   	leave  
c0108408:	c3                   	ret    

c0108409 <strcpy>:
 * To avoid overflows, the size of array pointed by @dst should be long enough to
 * contain the same string as @src (including the terminating null character), and
 * should not overlap in memory with @src.
 * */
char *
strcpy(char *dst, const char *src) {
c0108409:	f3 0f 1e fb          	endbr32 
c010840d:	55                   	push   %ebp
c010840e:	89 e5                	mov    %esp,%ebp
c0108410:	57                   	push   %edi
c0108411:	56                   	push   %esi
c0108412:	83 ec 20             	sub    $0x20,%esp
c0108415:	8b 45 08             	mov    0x8(%ebp),%eax
c0108418:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010841b:	8b 45 0c             	mov    0xc(%ebp),%eax
c010841e:	89 45 f0             	mov    %eax,-0x10(%ebp)
#ifndef __HAVE_ARCH_STRCPY
#define __HAVE_ARCH_STRCPY
static inline char *
__strcpy(char *dst, const char *src) {
    int d0, d1, d2;
    asm volatile (
c0108421:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0108424:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108427:	89 d1                	mov    %edx,%ecx
c0108429:	89 c2                	mov    %eax,%edx
c010842b:	89 ce                	mov    %ecx,%esi
c010842d:	89 d7                	mov    %edx,%edi
c010842f:	ac                   	lods   %ds:(%esi),%al
c0108430:	aa                   	stos   %al,%es:(%edi)
c0108431:	84 c0                	test   %al,%al
c0108433:	75 fa                	jne    c010842f <strcpy+0x26>
c0108435:	89 fa                	mov    %edi,%edx
c0108437:	89 f1                	mov    %esi,%ecx
c0108439:	89 4d ec             	mov    %ecx,-0x14(%ebp)
c010843c:	89 55 e8             	mov    %edx,-0x18(%ebp)
c010843f:	89 45 e4             	mov    %eax,-0x1c(%ebp)
        "stosb;"
        "testb %%al, %%al;"
        "jne 1b;"
        : "=&S" (d0), "=&D" (d1), "=&a" (d2)
        : "0" (src), "1" (dst) : "memory");
    return dst;
c0108442:	8b 45 f4             	mov    -0xc(%ebp),%eax
    char *p = dst;
    while ((*p ++ = *src ++) != '\0')
        /* nothing */;
    return dst;
#endif /* __HAVE_ARCH_STRCPY */
}
c0108445:	83 c4 20             	add    $0x20,%esp
c0108448:	5e                   	pop    %esi
c0108449:	5f                   	pop    %edi
c010844a:	5d                   	pop    %ebp
c010844b:	c3                   	ret    

c010844c <strncpy>:
 * @len:    maximum number of characters to be copied from @src
 *
 * The return value is @dst
 * */
char *
strncpy(char *dst, const char *src, size_t len) {
c010844c:	f3 0f 1e fb          	endbr32 
c0108450:	55                   	push   %ebp
c0108451:	89 e5                	mov    %esp,%ebp
c0108453:	83 ec 10             	sub    $0x10,%esp
    char *p = dst;
c0108456:	8b 45 08             	mov    0x8(%ebp),%eax
c0108459:	89 45 fc             	mov    %eax,-0x4(%ebp)
    while (len > 0) {
c010845c:	eb 1e                	jmp    c010847c <strncpy+0x30>
        if ((*p = *src) != '\0') {
c010845e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108461:	0f b6 10             	movzbl (%eax),%edx
c0108464:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0108467:	88 10                	mov    %dl,(%eax)
c0108469:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010846c:	0f b6 00             	movzbl (%eax),%eax
c010846f:	84 c0                	test   %al,%al
c0108471:	74 03                	je     c0108476 <strncpy+0x2a>
            src ++;
c0108473:	ff 45 0c             	incl   0xc(%ebp)
        }
        p ++, len --;
c0108476:	ff 45 fc             	incl   -0x4(%ebp)
c0108479:	ff 4d 10             	decl   0x10(%ebp)
    while (len > 0) {
c010847c:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0108480:	75 dc                	jne    c010845e <strncpy+0x12>
    }
    return dst;
c0108482:	8b 45 08             	mov    0x8(%ebp),%eax
}
c0108485:	c9                   	leave  
c0108486:	c3                   	ret    

c0108487 <strcmp>:
 * - A value greater than zero indicates that the first character that does
 *   not match has a greater value in @s1 than in @s2;
 * - And a value less than zero indicates the opposite.
 * */
int
strcmp(const char *s1, const char *s2) {
c0108487:	f3 0f 1e fb          	endbr32 
c010848b:	55                   	push   %ebp
c010848c:	89 e5                	mov    %esp,%ebp
c010848e:	57                   	push   %edi
c010848f:	56                   	push   %esi
c0108490:	83 ec 20             	sub    $0x20,%esp
c0108493:	8b 45 08             	mov    0x8(%ebp),%eax
c0108496:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108499:	8b 45 0c             	mov    0xc(%ebp),%eax
c010849c:	89 45 f0             	mov    %eax,-0x10(%ebp)
    asm volatile (
c010849f:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01084a2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01084a5:	89 d1                	mov    %edx,%ecx
c01084a7:	89 c2                	mov    %eax,%edx
c01084a9:	89 ce                	mov    %ecx,%esi
c01084ab:	89 d7                	mov    %edx,%edi
c01084ad:	ac                   	lods   %ds:(%esi),%al
c01084ae:	ae                   	scas   %es:(%edi),%al
c01084af:	75 08                	jne    c01084b9 <strcmp+0x32>
c01084b1:	84 c0                	test   %al,%al
c01084b3:	75 f8                	jne    c01084ad <strcmp+0x26>
c01084b5:	31 c0                	xor    %eax,%eax
c01084b7:	eb 04                	jmp    c01084bd <strcmp+0x36>
c01084b9:	19 c0                	sbb    %eax,%eax
c01084bb:	0c 01                	or     $0x1,%al
c01084bd:	89 fa                	mov    %edi,%edx
c01084bf:	89 f1                	mov    %esi,%ecx
c01084c1:	89 45 ec             	mov    %eax,-0x14(%ebp)
c01084c4:	89 4d e8             	mov    %ecx,-0x18(%ebp)
c01084c7:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    return ret;
c01084ca:	8b 45 ec             	mov    -0x14(%ebp),%eax
    while (*s1 != '\0' && *s1 == *s2) {
        s1 ++, s2 ++;
    }
    return (int)((unsigned char)*s1 - (unsigned char)*s2);
#endif /* __HAVE_ARCH_STRCMP */
}
c01084cd:	83 c4 20             	add    $0x20,%esp
c01084d0:	5e                   	pop    %esi
c01084d1:	5f                   	pop    %edi
c01084d2:	5d                   	pop    %ebp
c01084d3:	c3                   	ret    

c01084d4 <strncmp>:
 * they are equal to each other, it continues with the following pairs until
 * the characters differ, until a terminating null-character is reached, or
 * until @n characters match in both strings, whichever happens first.
 * */
int
strncmp(const char *s1, const char *s2, size_t n) {
c01084d4:	f3 0f 1e fb          	endbr32 
c01084d8:	55                   	push   %ebp
c01084d9:	89 e5                	mov    %esp,%ebp
    while (n > 0 && *s1 != '\0' && *s1 == *s2) {
c01084db:	eb 09                	jmp    c01084e6 <strncmp+0x12>
        n --, s1 ++, s2 ++;
c01084dd:	ff 4d 10             	decl   0x10(%ebp)
c01084e0:	ff 45 08             	incl   0x8(%ebp)
c01084e3:	ff 45 0c             	incl   0xc(%ebp)
    while (n > 0 && *s1 != '\0' && *s1 == *s2) {
c01084e6:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c01084ea:	74 1a                	je     c0108506 <strncmp+0x32>
c01084ec:	8b 45 08             	mov    0x8(%ebp),%eax
c01084ef:	0f b6 00             	movzbl (%eax),%eax
c01084f2:	84 c0                	test   %al,%al
c01084f4:	74 10                	je     c0108506 <strncmp+0x32>
c01084f6:	8b 45 08             	mov    0x8(%ebp),%eax
c01084f9:	0f b6 10             	movzbl (%eax),%edx
c01084fc:	8b 45 0c             	mov    0xc(%ebp),%eax
c01084ff:	0f b6 00             	movzbl (%eax),%eax
c0108502:	38 c2                	cmp    %al,%dl
c0108504:	74 d7                	je     c01084dd <strncmp+0x9>
    }
    return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2);
c0108506:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010850a:	74 18                	je     c0108524 <strncmp+0x50>
c010850c:	8b 45 08             	mov    0x8(%ebp),%eax
c010850f:	0f b6 00             	movzbl (%eax),%eax
c0108512:	0f b6 d0             	movzbl %al,%edx
c0108515:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108518:	0f b6 00             	movzbl (%eax),%eax
c010851b:	0f b6 c0             	movzbl %al,%eax
c010851e:	29 c2                	sub    %eax,%edx
c0108520:	89 d0                	mov    %edx,%eax
c0108522:	eb 05                	jmp    c0108529 <strncmp+0x55>
c0108524:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0108529:	5d                   	pop    %ebp
c010852a:	c3                   	ret    

c010852b <strchr>:
 *
 * The strchr() function returns a pointer to the first occurrence of
 * character in @s. If the value is not found, the function returns 'NULL'.
 * */
char *
strchr(const char *s, char c) {
c010852b:	f3 0f 1e fb          	endbr32 
c010852f:	55                   	push   %ebp
c0108530:	89 e5                	mov    %esp,%ebp
c0108532:	83 ec 04             	sub    $0x4,%esp
c0108535:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108538:	88 45 fc             	mov    %al,-0x4(%ebp)
    while (*s != '\0') {
c010853b:	eb 13                	jmp    c0108550 <strchr+0x25>
        if (*s == c) {
c010853d:	8b 45 08             	mov    0x8(%ebp),%eax
c0108540:	0f b6 00             	movzbl (%eax),%eax
c0108543:	38 45 fc             	cmp    %al,-0x4(%ebp)
c0108546:	75 05                	jne    c010854d <strchr+0x22>
            return (char *)s;
c0108548:	8b 45 08             	mov    0x8(%ebp),%eax
c010854b:	eb 12                	jmp    c010855f <strchr+0x34>
        }
        s ++;
c010854d:	ff 45 08             	incl   0x8(%ebp)
    while (*s != '\0') {
c0108550:	8b 45 08             	mov    0x8(%ebp),%eax
c0108553:	0f b6 00             	movzbl (%eax),%eax
c0108556:	84 c0                	test   %al,%al
c0108558:	75 e3                	jne    c010853d <strchr+0x12>
    }
    return NULL;
c010855a:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010855f:	c9                   	leave  
c0108560:	c3                   	ret    

c0108561 <strfind>:
 * The strfind() function is like strchr() except that if @c is
 * not found in @s, then it returns a pointer to the null byte at the
 * end of @s, rather than 'NULL'.
 * */
char *
strfind(const char *s, char c) {
c0108561:	f3 0f 1e fb          	endbr32 
c0108565:	55                   	push   %ebp
c0108566:	89 e5                	mov    %esp,%ebp
c0108568:	83 ec 04             	sub    $0x4,%esp
c010856b:	8b 45 0c             	mov    0xc(%ebp),%eax
c010856e:	88 45 fc             	mov    %al,-0x4(%ebp)
    while (*s != '\0') {
c0108571:	eb 0e                	jmp    c0108581 <strfind+0x20>
        if (*s == c) {
c0108573:	8b 45 08             	mov    0x8(%ebp),%eax
c0108576:	0f b6 00             	movzbl (%eax),%eax
c0108579:	38 45 fc             	cmp    %al,-0x4(%ebp)
c010857c:	74 0f                	je     c010858d <strfind+0x2c>
            break;
        }
        s ++;
c010857e:	ff 45 08             	incl   0x8(%ebp)
    while (*s != '\0') {
c0108581:	8b 45 08             	mov    0x8(%ebp),%eax
c0108584:	0f b6 00             	movzbl (%eax),%eax
c0108587:	84 c0                	test   %al,%al
c0108589:	75 e8                	jne    c0108573 <strfind+0x12>
c010858b:	eb 01                	jmp    c010858e <strfind+0x2d>
            break;
c010858d:	90                   	nop
    }
    return (char *)s;
c010858e:	8b 45 08             	mov    0x8(%ebp),%eax
}
c0108591:	c9                   	leave  
c0108592:	c3                   	ret    

c0108593 <strtol>:
 * an optional "0x" or "0X" prefix.
 *
 * The strtol() function returns the converted integral number as a long int value.
 * */
long
strtol(const char *s, char **endptr, int base) {
c0108593:	f3 0f 1e fb          	endbr32 
c0108597:	55                   	push   %ebp
c0108598:	89 e5                	mov    %esp,%ebp
c010859a:	83 ec 10             	sub    $0x10,%esp
    int neg = 0;
c010859d:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    long val = 0;
c01085a4:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%ebp)

    // gobble initial whitespace
    while (*s == ' ' || *s == '\t') {
c01085ab:	eb 03                	jmp    c01085b0 <strtol+0x1d>
        s ++;
c01085ad:	ff 45 08             	incl   0x8(%ebp)
    while (*s == ' ' || *s == '\t') {
c01085b0:	8b 45 08             	mov    0x8(%ebp),%eax
c01085b3:	0f b6 00             	movzbl (%eax),%eax
c01085b6:	3c 20                	cmp    $0x20,%al
c01085b8:	74 f3                	je     c01085ad <strtol+0x1a>
c01085ba:	8b 45 08             	mov    0x8(%ebp),%eax
c01085bd:	0f b6 00             	movzbl (%eax),%eax
c01085c0:	3c 09                	cmp    $0x9,%al
c01085c2:	74 e9                	je     c01085ad <strtol+0x1a>
    }

    // plus/minus sign
    if (*s == '+') {
c01085c4:	8b 45 08             	mov    0x8(%ebp),%eax
c01085c7:	0f b6 00             	movzbl (%eax),%eax
c01085ca:	3c 2b                	cmp    $0x2b,%al
c01085cc:	75 05                	jne    c01085d3 <strtol+0x40>
        s ++;
c01085ce:	ff 45 08             	incl   0x8(%ebp)
c01085d1:	eb 14                	jmp    c01085e7 <strtol+0x54>
    }
    else if (*s == '-') {
c01085d3:	8b 45 08             	mov    0x8(%ebp),%eax
c01085d6:	0f b6 00             	movzbl (%eax),%eax
c01085d9:	3c 2d                	cmp    $0x2d,%al
c01085db:	75 0a                	jne    c01085e7 <strtol+0x54>
        s ++, neg = 1;
c01085dd:	ff 45 08             	incl   0x8(%ebp)
c01085e0:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%ebp)
    }

    // hex or octal base prefix
    if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) {
c01085e7:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c01085eb:	74 06                	je     c01085f3 <strtol+0x60>
c01085ed:	83 7d 10 10          	cmpl   $0x10,0x10(%ebp)
c01085f1:	75 22                	jne    c0108615 <strtol+0x82>
c01085f3:	8b 45 08             	mov    0x8(%ebp),%eax
c01085f6:	0f b6 00             	movzbl (%eax),%eax
c01085f9:	3c 30                	cmp    $0x30,%al
c01085fb:	75 18                	jne    c0108615 <strtol+0x82>
c01085fd:	8b 45 08             	mov    0x8(%ebp),%eax
c0108600:	40                   	inc    %eax
c0108601:	0f b6 00             	movzbl (%eax),%eax
c0108604:	3c 78                	cmp    $0x78,%al
c0108606:	75 0d                	jne    c0108615 <strtol+0x82>
        s += 2, base = 16;
c0108608:	83 45 08 02          	addl   $0x2,0x8(%ebp)
c010860c:	c7 45 10 10 00 00 00 	movl   $0x10,0x10(%ebp)
c0108613:	eb 29                	jmp    c010863e <strtol+0xab>
    }
    else if (base == 0 && s[0] == '0') {
c0108615:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0108619:	75 16                	jne    c0108631 <strtol+0x9e>
c010861b:	8b 45 08             	mov    0x8(%ebp),%eax
c010861e:	0f b6 00             	movzbl (%eax),%eax
c0108621:	3c 30                	cmp    $0x30,%al
c0108623:	75 0c                	jne    c0108631 <strtol+0x9e>
        s ++, base = 8;
c0108625:	ff 45 08             	incl   0x8(%ebp)
c0108628:	c7 45 10 08 00 00 00 	movl   $0x8,0x10(%ebp)
c010862f:	eb 0d                	jmp    c010863e <strtol+0xab>
    }
    else if (base == 0) {
c0108631:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0108635:	75 07                	jne    c010863e <strtol+0xab>
        base = 10;
c0108637:	c7 45 10 0a 00 00 00 	movl   $0xa,0x10(%ebp)

    // digits
    while (1) {
        int dig;

        if (*s >= '0' && *s <= '9') {
c010863e:	8b 45 08             	mov    0x8(%ebp),%eax
c0108641:	0f b6 00             	movzbl (%eax),%eax
c0108644:	3c 2f                	cmp    $0x2f,%al
c0108646:	7e 1b                	jle    c0108663 <strtol+0xd0>
c0108648:	8b 45 08             	mov    0x8(%ebp),%eax
c010864b:	0f b6 00             	movzbl (%eax),%eax
c010864e:	3c 39                	cmp    $0x39,%al
c0108650:	7f 11                	jg     c0108663 <strtol+0xd0>
            dig = *s - '0';
c0108652:	8b 45 08             	mov    0x8(%ebp),%eax
c0108655:	0f b6 00             	movzbl (%eax),%eax
c0108658:	0f be c0             	movsbl %al,%eax
c010865b:	83 e8 30             	sub    $0x30,%eax
c010865e:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108661:	eb 48                	jmp    c01086ab <strtol+0x118>
        }
        else if (*s >= 'a' && *s <= 'z') {
c0108663:	8b 45 08             	mov    0x8(%ebp),%eax
c0108666:	0f b6 00             	movzbl (%eax),%eax
c0108669:	3c 60                	cmp    $0x60,%al
c010866b:	7e 1b                	jle    c0108688 <strtol+0xf5>
c010866d:	8b 45 08             	mov    0x8(%ebp),%eax
c0108670:	0f b6 00             	movzbl (%eax),%eax
c0108673:	3c 7a                	cmp    $0x7a,%al
c0108675:	7f 11                	jg     c0108688 <strtol+0xf5>
            dig = *s - 'a' + 10;
c0108677:	8b 45 08             	mov    0x8(%ebp),%eax
c010867a:	0f b6 00             	movzbl (%eax),%eax
c010867d:	0f be c0             	movsbl %al,%eax
c0108680:	83 e8 57             	sub    $0x57,%eax
c0108683:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108686:	eb 23                	jmp    c01086ab <strtol+0x118>
        }
        else if (*s >= 'A' && *s <= 'Z') {
c0108688:	8b 45 08             	mov    0x8(%ebp),%eax
c010868b:	0f b6 00             	movzbl (%eax),%eax
c010868e:	3c 40                	cmp    $0x40,%al
c0108690:	7e 3b                	jle    c01086cd <strtol+0x13a>
c0108692:	8b 45 08             	mov    0x8(%ebp),%eax
c0108695:	0f b6 00             	movzbl (%eax),%eax
c0108698:	3c 5a                	cmp    $0x5a,%al
c010869a:	7f 31                	jg     c01086cd <strtol+0x13a>
            dig = *s - 'A' + 10;
c010869c:	8b 45 08             	mov    0x8(%ebp),%eax
c010869f:	0f b6 00             	movzbl (%eax),%eax
c01086a2:	0f be c0             	movsbl %al,%eax
c01086a5:	83 e8 37             	sub    $0x37,%eax
c01086a8:	89 45 f4             	mov    %eax,-0xc(%ebp)
        }
        else {
            break;
        }
        if (dig >= base) {
c01086ab:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01086ae:	3b 45 10             	cmp    0x10(%ebp),%eax
c01086b1:	7d 19                	jge    c01086cc <strtol+0x139>
            break;
        }
        s ++, val = (val * base) + dig;
c01086b3:	ff 45 08             	incl   0x8(%ebp)
c01086b6:	8b 45 f8             	mov    -0x8(%ebp),%eax
c01086b9:	0f af 45 10          	imul   0x10(%ebp),%eax
c01086bd:	89 c2                	mov    %eax,%edx
c01086bf:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01086c2:	01 d0                	add    %edx,%eax
c01086c4:	89 45 f8             	mov    %eax,-0x8(%ebp)
    while (1) {
c01086c7:	e9 72 ff ff ff       	jmp    c010863e <strtol+0xab>
            break;
c01086cc:	90                   	nop
        // we don't properly detect overflow!
    }

    if (endptr) {
c01086cd:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c01086d1:	74 08                	je     c01086db <strtol+0x148>
        *endptr = (char *) s;
c01086d3:	8b 45 0c             	mov    0xc(%ebp),%eax
c01086d6:	8b 55 08             	mov    0x8(%ebp),%edx
c01086d9:	89 10                	mov    %edx,(%eax)
    }
    return (neg ? -val : val);
c01086db:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c01086df:	74 07                	je     c01086e8 <strtol+0x155>
c01086e1:	8b 45 f8             	mov    -0x8(%ebp),%eax
c01086e4:	f7 d8                	neg    %eax
c01086e6:	eb 03                	jmp    c01086eb <strtol+0x158>
c01086e8:	8b 45 f8             	mov    -0x8(%ebp),%eax
}
c01086eb:	c9                   	leave  
c01086ec:	c3                   	ret    

c01086ed <memset>:
 * @n:      number of bytes to be set to the value
 *
 * The memset() function returns @s.
 * */
void *
memset(void *s, char c, size_t n) {
c01086ed:	f3 0f 1e fb          	endbr32 
c01086f1:	55                   	push   %ebp
c01086f2:	89 e5                	mov    %esp,%ebp
c01086f4:	57                   	push   %edi
c01086f5:	83 ec 24             	sub    $0x24,%esp
c01086f8:	8b 45 0c             	mov    0xc(%ebp),%eax
c01086fb:	88 45 d8             	mov    %al,-0x28(%ebp)
#ifdef __HAVE_ARCH_MEMSET
    return __memset(s, c, n);
c01086fe:	0f be 55 d8          	movsbl -0x28(%ebp),%edx
c0108702:	8b 45 08             	mov    0x8(%ebp),%eax
c0108705:	89 45 f8             	mov    %eax,-0x8(%ebp)
c0108708:	88 55 f7             	mov    %dl,-0x9(%ebp)
c010870b:	8b 45 10             	mov    0x10(%ebp),%eax
c010870e:	89 45 f0             	mov    %eax,-0x10(%ebp)
#ifndef __HAVE_ARCH_MEMSET
#define __HAVE_ARCH_MEMSET
static inline void *
__memset(void *s, char c, size_t n) {
    int d0, d1;
    asm volatile (
c0108711:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c0108714:	0f b6 45 f7          	movzbl -0x9(%ebp),%eax
c0108718:	8b 55 f8             	mov    -0x8(%ebp),%edx
c010871b:	89 d7                	mov    %edx,%edi
c010871d:	f3 aa                	rep stos %al,%es:(%edi)
c010871f:	89 fa                	mov    %edi,%edx
c0108721:	89 4d ec             	mov    %ecx,-0x14(%ebp)
c0108724:	89 55 e8             	mov    %edx,-0x18(%ebp)
        "rep; stosb;"
        : "=&c" (d0), "=&D" (d1)
        : "0" (n), "a" (c), "1" (s)
        : "memory");
    return s;
c0108727:	8b 45 f8             	mov    -0x8(%ebp),%eax
    while (n -- > 0) {
        *p ++ = c;
    }
    return s;
#endif /* __HAVE_ARCH_MEMSET */
}
c010872a:	83 c4 24             	add    $0x24,%esp
c010872d:	5f                   	pop    %edi
c010872e:	5d                   	pop    %ebp
c010872f:	c3                   	ret    

c0108730 <memmove>:
 * @n:      number of bytes to copy
 *
 * The memmove() function returns @dst.
 * */
void *
memmove(void *dst, const void *src, size_t n) {
c0108730:	f3 0f 1e fb          	endbr32 
c0108734:	55                   	push   %ebp
c0108735:	89 e5                	mov    %esp,%ebp
c0108737:	57                   	push   %edi
c0108738:	56                   	push   %esi
c0108739:	53                   	push   %ebx
c010873a:	83 ec 30             	sub    $0x30,%esp
c010873d:	8b 45 08             	mov    0x8(%ebp),%eax
c0108740:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108743:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108746:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0108749:	8b 45 10             	mov    0x10(%ebp),%eax
c010874c:	89 45 e8             	mov    %eax,-0x18(%ebp)

#ifndef __HAVE_ARCH_MEMMOVE
#define __HAVE_ARCH_MEMMOVE
static inline void *
__memmove(void *dst, const void *src, size_t n) {
    if (dst < src) {
c010874f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108752:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0108755:	73 42                	jae    c0108799 <memmove+0x69>
c0108757:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010875a:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c010875d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108760:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0108763:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108766:	89 45 dc             	mov    %eax,-0x24(%ebp)
        "andl $3, %%ecx;"
        "jz 1f;"
        "rep; movsb;"
        "1:"
        : "=&c" (d0), "=&D" (d1), "=&S" (d2)
        : "0" (n / 4), "g" (n), "1" (dst), "2" (src)
c0108769:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010876c:	c1 e8 02             	shr    $0x2,%eax
c010876f:	89 c1                	mov    %eax,%ecx
    asm volatile (
c0108771:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0108774:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108777:	89 d7                	mov    %edx,%edi
c0108779:	89 c6                	mov    %eax,%esi
c010877b:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
c010877d:	8b 4d dc             	mov    -0x24(%ebp),%ecx
c0108780:	83 e1 03             	and    $0x3,%ecx
c0108783:	74 02                	je     c0108787 <memmove+0x57>
c0108785:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c0108787:	89 f0                	mov    %esi,%eax
c0108789:	89 fa                	mov    %edi,%edx
c010878b:	89 4d d8             	mov    %ecx,-0x28(%ebp)
c010878e:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0108791:	89 45 d0             	mov    %eax,-0x30(%ebp)
        : "memory");
    return dst;
c0108794:	8b 45 e4             	mov    -0x1c(%ebp),%eax
        return __memcpy(dst, src, n);
c0108797:	eb 36                	jmp    c01087cf <memmove+0x9f>
        : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst)
c0108799:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010879c:	8d 50 ff             	lea    -0x1(%eax),%edx
c010879f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01087a2:	01 c2                	add    %eax,%edx
c01087a4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01087a7:	8d 48 ff             	lea    -0x1(%eax),%ecx
c01087aa:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01087ad:	8d 1c 01             	lea    (%ecx,%eax,1),%ebx
    asm volatile (
c01087b0:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01087b3:	89 c1                	mov    %eax,%ecx
c01087b5:	89 d8                	mov    %ebx,%eax
c01087b7:	89 d6                	mov    %edx,%esi
c01087b9:	89 c7                	mov    %eax,%edi
c01087bb:	fd                   	std    
c01087bc:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c01087be:	fc                   	cld    
c01087bf:	89 f8                	mov    %edi,%eax
c01087c1:	89 f2                	mov    %esi,%edx
c01087c3:	89 4d cc             	mov    %ecx,-0x34(%ebp)
c01087c6:	89 55 c8             	mov    %edx,-0x38(%ebp)
c01087c9:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    return dst;
c01087cc:	8b 45 f0             	mov    -0x10(%ebp),%eax
            *d ++ = *s ++;
        }
    }
    return dst;
#endif /* __HAVE_ARCH_MEMMOVE */
}
c01087cf:	83 c4 30             	add    $0x30,%esp
c01087d2:	5b                   	pop    %ebx
c01087d3:	5e                   	pop    %esi
c01087d4:	5f                   	pop    %edi
c01087d5:	5d                   	pop    %ebp
c01087d6:	c3                   	ret    

c01087d7 <memcpy>:
 * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed
 * by both @src and @dst, should be at least @n bytes, and should not overlap
 * (for overlapping memory area, memmove is a safer approach).
 * */
void *
memcpy(void *dst, const void *src, size_t n) {
c01087d7:	f3 0f 1e fb          	endbr32 
c01087db:	55                   	push   %ebp
c01087dc:	89 e5                	mov    %esp,%ebp
c01087de:	57                   	push   %edi
c01087df:	56                   	push   %esi
c01087e0:	83 ec 20             	sub    $0x20,%esp
c01087e3:	8b 45 08             	mov    0x8(%ebp),%eax
c01087e6:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01087e9:	8b 45 0c             	mov    0xc(%ebp),%eax
c01087ec:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01087ef:	8b 45 10             	mov    0x10(%ebp),%eax
c01087f2:	89 45 ec             	mov    %eax,-0x14(%ebp)
        : "0" (n / 4), "g" (n), "1" (dst), "2" (src)
c01087f5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01087f8:	c1 e8 02             	shr    $0x2,%eax
c01087fb:	89 c1                	mov    %eax,%ecx
    asm volatile (
c01087fd:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108800:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108803:	89 d7                	mov    %edx,%edi
c0108805:	89 c6                	mov    %eax,%esi
c0108807:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
c0108809:	8b 4d ec             	mov    -0x14(%ebp),%ecx
c010880c:	83 e1 03             	and    $0x3,%ecx
c010880f:	74 02                	je     c0108813 <memcpy+0x3c>
c0108811:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c0108813:	89 f0                	mov    %esi,%eax
c0108815:	89 fa                	mov    %edi,%edx
c0108817:	89 4d e8             	mov    %ecx,-0x18(%ebp)
c010881a:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c010881d:	89 45 e0             	mov    %eax,-0x20(%ebp)
    return dst;
c0108820:	8b 45 f4             	mov    -0xc(%ebp),%eax
    while (n -- > 0) {
        *d ++ = *s ++;
    }
    return dst;
#endif /* __HAVE_ARCH_MEMCPY */
}
c0108823:	83 c4 20             	add    $0x20,%esp
c0108826:	5e                   	pop    %esi
c0108827:	5f                   	pop    %edi
c0108828:	5d                   	pop    %ebp
c0108829:	c3                   	ret    

c010882a <memcmp>:
 *   match in both memory blocks has a greater value in @v1 than in @v2
 *   as if evaluated as unsigned char values;
 * - And a value less than zero indicates the opposite.
 * */
int
memcmp(const void *v1, const void *v2, size_t n) {
c010882a:	f3 0f 1e fb          	endbr32 
c010882e:	55                   	push   %ebp
c010882f:	89 e5                	mov    %esp,%ebp
c0108831:	83 ec 10             	sub    $0x10,%esp
    const char *s1 = (const char *)v1;
c0108834:	8b 45 08             	mov    0x8(%ebp),%eax
c0108837:	89 45 fc             	mov    %eax,-0x4(%ebp)
    const char *s2 = (const char *)v2;
c010883a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010883d:	89 45 f8             	mov    %eax,-0x8(%ebp)
    while (n -- > 0) {
c0108840:	eb 2e                	jmp    c0108870 <memcmp+0x46>
        if (*s1 != *s2) {
c0108842:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0108845:	0f b6 10             	movzbl (%eax),%edx
c0108848:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010884b:	0f b6 00             	movzbl (%eax),%eax
c010884e:	38 c2                	cmp    %al,%dl
c0108850:	74 18                	je     c010886a <memcmp+0x40>
            return (int)((unsigned char)*s1 - (unsigned char)*s2);
c0108852:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0108855:	0f b6 00             	movzbl (%eax),%eax
c0108858:	0f b6 d0             	movzbl %al,%edx
c010885b:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010885e:	0f b6 00             	movzbl (%eax),%eax
c0108861:	0f b6 c0             	movzbl %al,%eax
c0108864:	29 c2                	sub    %eax,%edx
c0108866:	89 d0                	mov    %edx,%eax
c0108868:	eb 18                	jmp    c0108882 <memcmp+0x58>
        }
        s1 ++, s2 ++;
c010886a:	ff 45 fc             	incl   -0x4(%ebp)
c010886d:	ff 45 f8             	incl   -0x8(%ebp)
    while (n -- > 0) {
c0108870:	8b 45 10             	mov    0x10(%ebp),%eax
c0108873:	8d 50 ff             	lea    -0x1(%eax),%edx
c0108876:	89 55 10             	mov    %edx,0x10(%ebp)
c0108879:	85 c0                	test   %eax,%eax
c010887b:	75 c5                	jne    c0108842 <memcmp+0x18>
    }
    return 0;
c010887d:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0108882:	c9                   	leave  
c0108883:	c3                   	ret    

c0108884 <printnum>:
 * @width:      maximum number of digits, if the actual width is less than @width, use @padc instead
 * @padc:       character that padded on the left if the actual width is less than @width
 * */
static void
printnum(void (*putch)(int, void*), void *putdat,
        unsigned long long num, unsigned base, int width, int padc) {
c0108884:	f3 0f 1e fb          	endbr32 
c0108888:	55                   	push   %ebp
c0108889:	89 e5                	mov    %esp,%ebp
c010888b:	83 ec 58             	sub    $0x58,%esp
c010888e:	8b 45 10             	mov    0x10(%ebp),%eax
c0108891:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0108894:	8b 45 14             	mov    0x14(%ebp),%eax
c0108897:	89 45 d4             	mov    %eax,-0x2c(%ebp)
    unsigned long long result = num;
c010889a:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010889d:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01088a0:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01088a3:	89 55 ec             	mov    %edx,-0x14(%ebp)
    unsigned mod = do_div(result, base);
c01088a6:	8b 45 18             	mov    0x18(%ebp),%eax
c01088a9:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c01088ac:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01088af:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01088b2:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01088b5:	89 55 f0             	mov    %edx,-0x10(%ebp)
c01088b8:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01088bb:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01088be:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01088c2:	74 1c                	je     c01088e0 <printnum+0x5c>
c01088c4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01088c7:	ba 00 00 00 00       	mov    $0x0,%edx
c01088cc:	f7 75 e4             	divl   -0x1c(%ebp)
c01088cf:	89 55 f4             	mov    %edx,-0xc(%ebp)
c01088d2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01088d5:	ba 00 00 00 00       	mov    $0x0,%edx
c01088da:	f7 75 e4             	divl   -0x1c(%ebp)
c01088dd:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01088e0:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01088e3:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01088e6:	f7 75 e4             	divl   -0x1c(%ebp)
c01088e9:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01088ec:	89 55 dc             	mov    %edx,-0x24(%ebp)
c01088ef:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01088f2:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01088f5:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01088f8:	89 55 ec             	mov    %edx,-0x14(%ebp)
c01088fb:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01088fe:	89 45 d8             	mov    %eax,-0x28(%ebp)

    // first recursively print all preceding (more significant) digits
    if (num >= base) {
c0108901:	8b 45 18             	mov    0x18(%ebp),%eax
c0108904:	ba 00 00 00 00       	mov    $0x0,%edx
c0108909:	8b 4d d4             	mov    -0x2c(%ebp),%ecx
c010890c:	39 45 d0             	cmp    %eax,-0x30(%ebp)
c010890f:	19 d1                	sbb    %edx,%ecx
c0108911:	72 4c                	jb     c010895f <printnum+0xdb>
        printnum(putch, putdat, result, base, width - 1, padc);
c0108913:	8b 45 1c             	mov    0x1c(%ebp),%eax
c0108916:	8d 50 ff             	lea    -0x1(%eax),%edx
c0108919:	8b 45 20             	mov    0x20(%ebp),%eax
c010891c:	89 44 24 18          	mov    %eax,0x18(%esp)
c0108920:	89 54 24 14          	mov    %edx,0x14(%esp)
c0108924:	8b 45 18             	mov    0x18(%ebp),%eax
c0108927:	89 44 24 10          	mov    %eax,0x10(%esp)
c010892b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010892e:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0108931:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108935:	89 54 24 0c          	mov    %edx,0xc(%esp)
c0108939:	8b 45 0c             	mov    0xc(%ebp),%eax
c010893c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108940:	8b 45 08             	mov    0x8(%ebp),%eax
c0108943:	89 04 24             	mov    %eax,(%esp)
c0108946:	e8 39 ff ff ff       	call   c0108884 <printnum>
c010894b:	eb 1b                	jmp    c0108968 <printnum+0xe4>
    } else {
        // print any needed pad characters before first digit
        while (-- width > 0)
            putch(padc, putdat);
c010894d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108950:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108954:	8b 45 20             	mov    0x20(%ebp),%eax
c0108957:	89 04 24             	mov    %eax,(%esp)
c010895a:	8b 45 08             	mov    0x8(%ebp),%eax
c010895d:	ff d0                	call   *%eax
        while (-- width > 0)
c010895f:	ff 4d 1c             	decl   0x1c(%ebp)
c0108962:	83 7d 1c 00          	cmpl   $0x0,0x1c(%ebp)
c0108966:	7f e5                	jg     c010894d <printnum+0xc9>
    }
    // then print this (the least significant) digit
    putch("0123456789abcdef"[mod], putdat);
c0108968:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010896b:	05 e4 ae 10 c0       	add    $0xc010aee4,%eax
c0108970:	0f b6 00             	movzbl (%eax),%eax
c0108973:	0f be c0             	movsbl %al,%eax
c0108976:	8b 55 0c             	mov    0xc(%ebp),%edx
c0108979:	89 54 24 04          	mov    %edx,0x4(%esp)
c010897d:	89 04 24             	mov    %eax,(%esp)
c0108980:	8b 45 08             	mov    0x8(%ebp),%eax
c0108983:	ff d0                	call   *%eax
}
c0108985:	90                   	nop
c0108986:	c9                   	leave  
c0108987:	c3                   	ret    

c0108988 <getuint>:
 * getuint - get an unsigned int of various possible sizes from a varargs list
 * @ap:         a varargs list pointer
 * @lflag:      determines the size of the vararg that @ap points to
 * */
static unsigned long long
getuint(va_list *ap, int lflag) {
c0108988:	f3 0f 1e fb          	endbr32 
c010898c:	55                   	push   %ebp
c010898d:	89 e5                	mov    %esp,%ebp
    if (lflag >= 2) {
c010898f:	83 7d 0c 01          	cmpl   $0x1,0xc(%ebp)
c0108993:	7e 14                	jle    c01089a9 <getuint+0x21>
        return va_arg(*ap, unsigned long long);
c0108995:	8b 45 08             	mov    0x8(%ebp),%eax
c0108998:	8b 00                	mov    (%eax),%eax
c010899a:	8d 48 08             	lea    0x8(%eax),%ecx
c010899d:	8b 55 08             	mov    0x8(%ebp),%edx
c01089a0:	89 0a                	mov    %ecx,(%edx)
c01089a2:	8b 50 04             	mov    0x4(%eax),%edx
c01089a5:	8b 00                	mov    (%eax),%eax
c01089a7:	eb 30                	jmp    c01089d9 <getuint+0x51>
    }
    else if (lflag) {
c01089a9:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c01089ad:	74 16                	je     c01089c5 <getuint+0x3d>
        return va_arg(*ap, unsigned long);
c01089af:	8b 45 08             	mov    0x8(%ebp),%eax
c01089b2:	8b 00                	mov    (%eax),%eax
c01089b4:	8d 48 04             	lea    0x4(%eax),%ecx
c01089b7:	8b 55 08             	mov    0x8(%ebp),%edx
c01089ba:	89 0a                	mov    %ecx,(%edx)
c01089bc:	8b 00                	mov    (%eax),%eax
c01089be:	ba 00 00 00 00       	mov    $0x0,%edx
c01089c3:	eb 14                	jmp    c01089d9 <getuint+0x51>
    }
    else {
        return va_arg(*ap, unsigned int);
c01089c5:	8b 45 08             	mov    0x8(%ebp),%eax
c01089c8:	8b 00                	mov    (%eax),%eax
c01089ca:	8d 48 04             	lea    0x4(%eax),%ecx
c01089cd:	8b 55 08             	mov    0x8(%ebp),%edx
c01089d0:	89 0a                	mov    %ecx,(%edx)
c01089d2:	8b 00                	mov    (%eax),%eax
c01089d4:	ba 00 00 00 00       	mov    $0x0,%edx
    }
}
c01089d9:	5d                   	pop    %ebp
c01089da:	c3                   	ret    

c01089db <getint>:
 * getint - same as getuint but signed, we can't use getuint because of sign extension
 * @ap:         a varargs list pointer
 * @lflag:      determines the size of the vararg that @ap points to
 * */
static long long
getint(va_list *ap, int lflag) {
c01089db:	f3 0f 1e fb          	endbr32 
c01089df:	55                   	push   %ebp
c01089e0:	89 e5                	mov    %esp,%ebp
    if (lflag >= 2) {
c01089e2:	83 7d 0c 01          	cmpl   $0x1,0xc(%ebp)
c01089e6:	7e 14                	jle    c01089fc <getint+0x21>
        return va_arg(*ap, long long);
c01089e8:	8b 45 08             	mov    0x8(%ebp),%eax
c01089eb:	8b 00                	mov    (%eax),%eax
c01089ed:	8d 48 08             	lea    0x8(%eax),%ecx
c01089f0:	8b 55 08             	mov    0x8(%ebp),%edx
c01089f3:	89 0a                	mov    %ecx,(%edx)
c01089f5:	8b 50 04             	mov    0x4(%eax),%edx
c01089f8:	8b 00                	mov    (%eax),%eax
c01089fa:	eb 28                	jmp    c0108a24 <getint+0x49>
    }
    else if (lflag) {
c01089fc:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0108a00:	74 12                	je     c0108a14 <getint+0x39>
        return va_arg(*ap, long);
c0108a02:	8b 45 08             	mov    0x8(%ebp),%eax
c0108a05:	8b 00                	mov    (%eax),%eax
c0108a07:	8d 48 04             	lea    0x4(%eax),%ecx
c0108a0a:	8b 55 08             	mov    0x8(%ebp),%edx
c0108a0d:	89 0a                	mov    %ecx,(%edx)
c0108a0f:	8b 00                	mov    (%eax),%eax
c0108a11:	99                   	cltd   
c0108a12:	eb 10                	jmp    c0108a24 <getint+0x49>
    }
    else {
        return va_arg(*ap, int);
c0108a14:	8b 45 08             	mov    0x8(%ebp),%eax
c0108a17:	8b 00                	mov    (%eax),%eax
c0108a19:	8d 48 04             	lea    0x4(%eax),%ecx
c0108a1c:	8b 55 08             	mov    0x8(%ebp),%edx
c0108a1f:	89 0a                	mov    %ecx,(%edx)
c0108a21:	8b 00                	mov    (%eax),%eax
c0108a23:	99                   	cltd   
    }
}
c0108a24:	5d                   	pop    %ebp
c0108a25:	c3                   	ret    

c0108a26 <printfmt>:
 * @putch:      specified putch function, print a single character
 * @putdat:     used by @putch function
 * @fmt:        the format string to use
 * */
void
printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) {
c0108a26:	f3 0f 1e fb          	endbr32 
c0108a2a:	55                   	push   %ebp
c0108a2b:	89 e5                	mov    %esp,%ebp
c0108a2d:	83 ec 28             	sub    $0x28,%esp
    va_list ap;

    va_start(ap, fmt);
c0108a30:	8d 45 14             	lea    0x14(%ebp),%eax
c0108a33:	89 45 f4             	mov    %eax,-0xc(%ebp)
    vprintfmt(putch, putdat, fmt, ap);
c0108a36:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108a39:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0108a3d:	8b 45 10             	mov    0x10(%ebp),%eax
c0108a40:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108a44:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108a47:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108a4b:	8b 45 08             	mov    0x8(%ebp),%eax
c0108a4e:	89 04 24             	mov    %eax,(%esp)
c0108a51:	e8 03 00 00 00       	call   c0108a59 <vprintfmt>
    va_end(ap);
}
c0108a56:	90                   	nop
c0108a57:	c9                   	leave  
c0108a58:	c3                   	ret    

c0108a59 <vprintfmt>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want printfmt() instead.
 * */
void
vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) {
c0108a59:	f3 0f 1e fb          	endbr32 
c0108a5d:	55                   	push   %ebp
c0108a5e:	89 e5                	mov    %esp,%ebp
c0108a60:	56                   	push   %esi
c0108a61:	53                   	push   %ebx
c0108a62:	83 ec 40             	sub    $0x40,%esp
    register int ch, err;
    unsigned long long num;
    int base, width, precision, lflag, altflag;

    while (1) {
        while ((ch = *(unsigned char *)fmt ++) != '%') {
c0108a65:	eb 17                	jmp    c0108a7e <vprintfmt+0x25>
            if (ch == '\0') {
c0108a67:	85 db                	test   %ebx,%ebx
c0108a69:	0f 84 c0 03 00 00    	je     c0108e2f <vprintfmt+0x3d6>
                return;
            }
            putch(ch, putdat);
c0108a6f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108a72:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108a76:	89 1c 24             	mov    %ebx,(%esp)
c0108a79:	8b 45 08             	mov    0x8(%ebp),%eax
c0108a7c:	ff d0                	call   *%eax
        while ((ch = *(unsigned char *)fmt ++) != '%') {
c0108a7e:	8b 45 10             	mov    0x10(%ebp),%eax
c0108a81:	8d 50 01             	lea    0x1(%eax),%edx
c0108a84:	89 55 10             	mov    %edx,0x10(%ebp)
c0108a87:	0f b6 00             	movzbl (%eax),%eax
c0108a8a:	0f b6 d8             	movzbl %al,%ebx
c0108a8d:	83 fb 25             	cmp    $0x25,%ebx
c0108a90:	75 d5                	jne    c0108a67 <vprintfmt+0xe>
        }

        // Process a %-escape sequence
        char padc = ' ';
c0108a92:	c6 45 db 20          	movb   $0x20,-0x25(%ebp)
        width = precision = -1;
c0108a96:	c7 45 e4 ff ff ff ff 	movl   $0xffffffff,-0x1c(%ebp)
c0108a9d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108aa0:	89 45 e8             	mov    %eax,-0x18(%ebp)
        lflag = altflag = 0;
c0108aa3:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c0108aaa:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108aad:	89 45 e0             	mov    %eax,-0x20(%ebp)

    reswitch:
        switch (ch = *(unsigned char *)fmt ++) {
c0108ab0:	8b 45 10             	mov    0x10(%ebp),%eax
c0108ab3:	8d 50 01             	lea    0x1(%eax),%edx
c0108ab6:	89 55 10             	mov    %edx,0x10(%ebp)
c0108ab9:	0f b6 00             	movzbl (%eax),%eax
c0108abc:	0f b6 d8             	movzbl %al,%ebx
c0108abf:	8d 43 dd             	lea    -0x23(%ebx),%eax
c0108ac2:	83 f8 55             	cmp    $0x55,%eax
c0108ac5:	0f 87 38 03 00 00    	ja     c0108e03 <vprintfmt+0x3aa>
c0108acb:	8b 04 85 08 af 10 c0 	mov    -0x3fef50f8(,%eax,4),%eax
c0108ad2:	3e ff e0             	notrack jmp *%eax

        // flag to pad on the right
        case '-':
            padc = '-';
c0108ad5:	c6 45 db 2d          	movb   $0x2d,-0x25(%ebp)
            goto reswitch;
c0108ad9:	eb d5                	jmp    c0108ab0 <vprintfmt+0x57>

        // flag to pad with 0's instead of spaces
        case '0':
            padc = '0';
c0108adb:	c6 45 db 30          	movb   $0x30,-0x25(%ebp)
            goto reswitch;
c0108adf:	eb cf                	jmp    c0108ab0 <vprintfmt+0x57>

        // width field
        case '1' ... '9':
            for (precision = 0; ; ++ fmt) {
c0108ae1:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
                precision = precision * 10 + ch - '0';
c0108ae8:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0108aeb:	89 d0                	mov    %edx,%eax
c0108aed:	c1 e0 02             	shl    $0x2,%eax
c0108af0:	01 d0                	add    %edx,%eax
c0108af2:	01 c0                	add    %eax,%eax
c0108af4:	01 d8                	add    %ebx,%eax
c0108af6:	83 e8 30             	sub    $0x30,%eax
c0108af9:	89 45 e4             	mov    %eax,-0x1c(%ebp)
                ch = *fmt;
c0108afc:	8b 45 10             	mov    0x10(%ebp),%eax
c0108aff:	0f b6 00             	movzbl (%eax),%eax
c0108b02:	0f be d8             	movsbl %al,%ebx
                if (ch < '0' || ch > '9') {
c0108b05:	83 fb 2f             	cmp    $0x2f,%ebx
c0108b08:	7e 38                	jle    c0108b42 <vprintfmt+0xe9>
c0108b0a:	83 fb 39             	cmp    $0x39,%ebx
c0108b0d:	7f 33                	jg     c0108b42 <vprintfmt+0xe9>
            for (precision = 0; ; ++ fmt) {
c0108b0f:	ff 45 10             	incl   0x10(%ebp)
                precision = precision * 10 + ch - '0';
c0108b12:	eb d4                	jmp    c0108ae8 <vprintfmt+0x8f>
                }
            }
            goto process_precision;

        case '*':
            precision = va_arg(ap, int);
c0108b14:	8b 45 14             	mov    0x14(%ebp),%eax
c0108b17:	8d 50 04             	lea    0x4(%eax),%edx
c0108b1a:	89 55 14             	mov    %edx,0x14(%ebp)
c0108b1d:	8b 00                	mov    (%eax),%eax
c0108b1f:	89 45 e4             	mov    %eax,-0x1c(%ebp)
            goto process_precision;
c0108b22:	eb 1f                	jmp    c0108b43 <vprintfmt+0xea>

        case '.':
            if (width < 0)
c0108b24:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0108b28:	79 86                	jns    c0108ab0 <vprintfmt+0x57>
                width = 0;
c0108b2a:	c7 45 e8 00 00 00 00 	movl   $0x0,-0x18(%ebp)
            goto reswitch;
c0108b31:	e9 7a ff ff ff       	jmp    c0108ab0 <vprintfmt+0x57>

        case '#':
            altflag = 1;
c0108b36:	c7 45 dc 01 00 00 00 	movl   $0x1,-0x24(%ebp)
            goto reswitch;
c0108b3d:	e9 6e ff ff ff       	jmp    c0108ab0 <vprintfmt+0x57>
            goto process_precision;
c0108b42:	90                   	nop

        process_precision:
            if (width < 0)
c0108b43:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0108b47:	0f 89 63 ff ff ff    	jns    c0108ab0 <vprintfmt+0x57>
                width = precision, precision = -1;
c0108b4d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108b50:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0108b53:	c7 45 e4 ff ff ff ff 	movl   $0xffffffff,-0x1c(%ebp)
            goto reswitch;
c0108b5a:	e9 51 ff ff ff       	jmp    c0108ab0 <vprintfmt+0x57>

        // long flag (doubled for long long)
        case 'l':
            lflag ++;
c0108b5f:	ff 45 e0             	incl   -0x20(%ebp)
            goto reswitch;
c0108b62:	e9 49 ff ff ff       	jmp    c0108ab0 <vprintfmt+0x57>

        // character
        case 'c':
            putch(va_arg(ap, int), putdat);
c0108b67:	8b 45 14             	mov    0x14(%ebp),%eax
c0108b6a:	8d 50 04             	lea    0x4(%eax),%edx
c0108b6d:	89 55 14             	mov    %edx,0x14(%ebp)
c0108b70:	8b 00                	mov    (%eax),%eax
c0108b72:	8b 55 0c             	mov    0xc(%ebp),%edx
c0108b75:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108b79:	89 04 24             	mov    %eax,(%esp)
c0108b7c:	8b 45 08             	mov    0x8(%ebp),%eax
c0108b7f:	ff d0                	call   *%eax
            break;
c0108b81:	e9 a4 02 00 00       	jmp    c0108e2a <vprintfmt+0x3d1>

        // error message
        case 'e':
            err = va_arg(ap, int);
c0108b86:	8b 45 14             	mov    0x14(%ebp),%eax
c0108b89:	8d 50 04             	lea    0x4(%eax),%edx
c0108b8c:	89 55 14             	mov    %edx,0x14(%ebp)
c0108b8f:	8b 18                	mov    (%eax),%ebx
            if (err < 0) {
c0108b91:	85 db                	test   %ebx,%ebx
c0108b93:	79 02                	jns    c0108b97 <vprintfmt+0x13e>
                err = -err;
c0108b95:	f7 db                	neg    %ebx
            }
            if (err > MAXERROR || (p = error_string[err]) == NULL) {
c0108b97:	83 fb 06             	cmp    $0x6,%ebx
c0108b9a:	7f 0b                	jg     c0108ba7 <vprintfmt+0x14e>
c0108b9c:	8b 34 9d c8 ae 10 c0 	mov    -0x3fef5138(,%ebx,4),%esi
c0108ba3:	85 f6                	test   %esi,%esi
c0108ba5:	75 23                	jne    c0108bca <vprintfmt+0x171>
                printfmt(putch, putdat, "error %d", err);
c0108ba7:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c0108bab:	c7 44 24 08 f5 ae 10 	movl   $0xc010aef5,0x8(%esp)
c0108bb2:	c0 
c0108bb3:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108bb6:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108bba:	8b 45 08             	mov    0x8(%ebp),%eax
c0108bbd:	89 04 24             	mov    %eax,(%esp)
c0108bc0:	e8 61 fe ff ff       	call   c0108a26 <printfmt>
            }
            else {
                printfmt(putch, putdat, "%s", p);
            }
            break;
c0108bc5:	e9 60 02 00 00       	jmp    c0108e2a <vprintfmt+0x3d1>
                printfmt(putch, putdat, "%s", p);
c0108bca:	89 74 24 0c          	mov    %esi,0xc(%esp)
c0108bce:	c7 44 24 08 fe ae 10 	movl   $0xc010aefe,0x8(%esp)
c0108bd5:	c0 
c0108bd6:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108bd9:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108bdd:	8b 45 08             	mov    0x8(%ebp),%eax
c0108be0:	89 04 24             	mov    %eax,(%esp)
c0108be3:	e8 3e fe ff ff       	call   c0108a26 <printfmt>
            break;
c0108be8:	e9 3d 02 00 00       	jmp    c0108e2a <vprintfmt+0x3d1>

        // string
        case 's':
            if ((p = va_arg(ap, char *)) == NULL) {
c0108bed:	8b 45 14             	mov    0x14(%ebp),%eax
c0108bf0:	8d 50 04             	lea    0x4(%eax),%edx
c0108bf3:	89 55 14             	mov    %edx,0x14(%ebp)
c0108bf6:	8b 30                	mov    (%eax),%esi
c0108bf8:	85 f6                	test   %esi,%esi
c0108bfa:	75 05                	jne    c0108c01 <vprintfmt+0x1a8>
                p = "(null)";
c0108bfc:	be 01 af 10 c0       	mov    $0xc010af01,%esi
            }
            if (width > 0 && padc != '-') {
c0108c01:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0108c05:	7e 76                	jle    c0108c7d <vprintfmt+0x224>
c0108c07:	80 7d db 2d          	cmpb   $0x2d,-0x25(%ebp)
c0108c0b:	74 70                	je     c0108c7d <vprintfmt+0x224>
                for (width -= strnlen(p, precision); width > 0; width --) {
c0108c0d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108c10:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108c14:	89 34 24             	mov    %esi,(%esp)
c0108c17:	e8 ba f7 ff ff       	call   c01083d6 <strnlen>
c0108c1c:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0108c1f:	29 c2                	sub    %eax,%edx
c0108c21:	89 d0                	mov    %edx,%eax
c0108c23:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0108c26:	eb 16                	jmp    c0108c3e <vprintfmt+0x1e5>
                    putch(padc, putdat);
c0108c28:	0f be 45 db          	movsbl -0x25(%ebp),%eax
c0108c2c:	8b 55 0c             	mov    0xc(%ebp),%edx
c0108c2f:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108c33:	89 04 24             	mov    %eax,(%esp)
c0108c36:	8b 45 08             	mov    0x8(%ebp),%eax
c0108c39:	ff d0                	call   *%eax
                for (width -= strnlen(p, precision); width > 0; width --) {
c0108c3b:	ff 4d e8             	decl   -0x18(%ebp)
c0108c3e:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0108c42:	7f e4                	jg     c0108c28 <vprintfmt+0x1cf>
                }
            }
            for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) {
c0108c44:	eb 37                	jmp    c0108c7d <vprintfmt+0x224>
                if (altflag && (ch < ' ' || ch > '~')) {
c0108c46:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0108c4a:	74 1f                	je     c0108c6b <vprintfmt+0x212>
c0108c4c:	83 fb 1f             	cmp    $0x1f,%ebx
c0108c4f:	7e 05                	jle    c0108c56 <vprintfmt+0x1fd>
c0108c51:	83 fb 7e             	cmp    $0x7e,%ebx
c0108c54:	7e 15                	jle    c0108c6b <vprintfmt+0x212>
                    putch('?', putdat);
c0108c56:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108c59:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108c5d:	c7 04 24 3f 00 00 00 	movl   $0x3f,(%esp)
c0108c64:	8b 45 08             	mov    0x8(%ebp),%eax
c0108c67:	ff d0                	call   *%eax
c0108c69:	eb 0f                	jmp    c0108c7a <vprintfmt+0x221>
                }
                else {
                    putch(ch, putdat);
c0108c6b:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108c6e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108c72:	89 1c 24             	mov    %ebx,(%esp)
c0108c75:	8b 45 08             	mov    0x8(%ebp),%eax
c0108c78:	ff d0                	call   *%eax
            for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) {
c0108c7a:	ff 4d e8             	decl   -0x18(%ebp)
c0108c7d:	89 f0                	mov    %esi,%eax
c0108c7f:	8d 70 01             	lea    0x1(%eax),%esi
c0108c82:	0f b6 00             	movzbl (%eax),%eax
c0108c85:	0f be d8             	movsbl %al,%ebx
c0108c88:	85 db                	test   %ebx,%ebx
c0108c8a:	74 27                	je     c0108cb3 <vprintfmt+0x25a>
c0108c8c:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0108c90:	78 b4                	js     c0108c46 <vprintfmt+0x1ed>
c0108c92:	ff 4d e4             	decl   -0x1c(%ebp)
c0108c95:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0108c99:	79 ab                	jns    c0108c46 <vprintfmt+0x1ed>
                }
            }
            for (; width > 0; width --) {
c0108c9b:	eb 16                	jmp    c0108cb3 <vprintfmt+0x25a>
                putch(' ', putdat);
c0108c9d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108ca0:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108ca4:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c0108cab:	8b 45 08             	mov    0x8(%ebp),%eax
c0108cae:	ff d0                	call   *%eax
            for (; width > 0; width --) {
c0108cb0:	ff 4d e8             	decl   -0x18(%ebp)
c0108cb3:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0108cb7:	7f e4                	jg     c0108c9d <vprintfmt+0x244>
            }
            break;
c0108cb9:	e9 6c 01 00 00       	jmp    c0108e2a <vprintfmt+0x3d1>

        // (signed) decimal
        case 'd':
            num = getint(&ap, lflag);
c0108cbe:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108cc1:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108cc5:	8d 45 14             	lea    0x14(%ebp),%eax
c0108cc8:	89 04 24             	mov    %eax,(%esp)
c0108ccb:	e8 0b fd ff ff       	call   c01089db <getint>
c0108cd0:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108cd3:	89 55 f4             	mov    %edx,-0xc(%ebp)
            if ((long long)num < 0) {
c0108cd6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108cd9:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108cdc:	85 d2                	test   %edx,%edx
c0108cde:	79 26                	jns    c0108d06 <vprintfmt+0x2ad>
                putch('-', putdat);
c0108ce0:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108ce3:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108ce7:	c7 04 24 2d 00 00 00 	movl   $0x2d,(%esp)
c0108cee:	8b 45 08             	mov    0x8(%ebp),%eax
c0108cf1:	ff d0                	call   *%eax
                num = -(long long)num;
c0108cf3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108cf6:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108cf9:	f7 d8                	neg    %eax
c0108cfb:	83 d2 00             	adc    $0x0,%edx
c0108cfe:	f7 da                	neg    %edx
c0108d00:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108d03:	89 55 f4             	mov    %edx,-0xc(%ebp)
            }
            base = 10;
c0108d06:	c7 45 ec 0a 00 00 00 	movl   $0xa,-0x14(%ebp)
            goto number;
c0108d0d:	e9 a8 00 00 00       	jmp    c0108dba <vprintfmt+0x361>

        // unsigned decimal
        case 'u':
            num = getuint(&ap, lflag);
c0108d12:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108d15:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108d19:	8d 45 14             	lea    0x14(%ebp),%eax
c0108d1c:	89 04 24             	mov    %eax,(%esp)
c0108d1f:	e8 64 fc ff ff       	call   c0108988 <getuint>
c0108d24:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108d27:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 10;
c0108d2a:	c7 45 ec 0a 00 00 00 	movl   $0xa,-0x14(%ebp)
            goto number;
c0108d31:	e9 84 00 00 00       	jmp    c0108dba <vprintfmt+0x361>

        // (unsigned) octal
        case 'o':
            num = getuint(&ap, lflag);
c0108d36:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108d39:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108d3d:	8d 45 14             	lea    0x14(%ebp),%eax
c0108d40:	89 04 24             	mov    %eax,(%esp)
c0108d43:	e8 40 fc ff ff       	call   c0108988 <getuint>
c0108d48:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108d4b:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 8;
c0108d4e:	c7 45 ec 08 00 00 00 	movl   $0x8,-0x14(%ebp)
            goto number;
c0108d55:	eb 63                	jmp    c0108dba <vprintfmt+0x361>

        // pointer
        case 'p':
            putch('0', putdat);
c0108d57:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108d5a:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108d5e:	c7 04 24 30 00 00 00 	movl   $0x30,(%esp)
c0108d65:	8b 45 08             	mov    0x8(%ebp),%eax
c0108d68:	ff d0                	call   *%eax
            putch('x', putdat);
c0108d6a:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108d6d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108d71:	c7 04 24 78 00 00 00 	movl   $0x78,(%esp)
c0108d78:	8b 45 08             	mov    0x8(%ebp),%eax
c0108d7b:	ff d0                	call   *%eax
            num = (unsigned long long)(uintptr_t)va_arg(ap, void *);
c0108d7d:	8b 45 14             	mov    0x14(%ebp),%eax
c0108d80:	8d 50 04             	lea    0x4(%eax),%edx
c0108d83:	89 55 14             	mov    %edx,0x14(%ebp)
c0108d86:	8b 00                	mov    (%eax),%eax
c0108d88:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108d8b:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
            base = 16;
c0108d92:	c7 45 ec 10 00 00 00 	movl   $0x10,-0x14(%ebp)
            goto number;
c0108d99:	eb 1f                	jmp    c0108dba <vprintfmt+0x361>

        // (unsigned) hexadecimal
        case 'x':
            num = getuint(&ap, lflag);
c0108d9b:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108d9e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108da2:	8d 45 14             	lea    0x14(%ebp),%eax
c0108da5:	89 04 24             	mov    %eax,(%esp)
c0108da8:	e8 db fb ff ff       	call   c0108988 <getuint>
c0108dad:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108db0:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 16;
c0108db3:	c7 45 ec 10 00 00 00 	movl   $0x10,-0x14(%ebp)
        number:
            printnum(putch, putdat, num, base, width, padc);
c0108dba:	0f be 55 db          	movsbl -0x25(%ebp),%edx
c0108dbe:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108dc1:	89 54 24 18          	mov    %edx,0x18(%esp)
c0108dc5:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0108dc8:	89 54 24 14          	mov    %edx,0x14(%esp)
c0108dcc:	89 44 24 10          	mov    %eax,0x10(%esp)
c0108dd0:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108dd3:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108dd6:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108dda:	89 54 24 0c          	mov    %edx,0xc(%esp)
c0108dde:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108de1:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108de5:	8b 45 08             	mov    0x8(%ebp),%eax
c0108de8:	89 04 24             	mov    %eax,(%esp)
c0108deb:	e8 94 fa ff ff       	call   c0108884 <printnum>
            break;
c0108df0:	eb 38                	jmp    c0108e2a <vprintfmt+0x3d1>

        // escaped '%' character
        case '%':
            putch(ch, putdat);
c0108df2:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108df5:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108df9:	89 1c 24             	mov    %ebx,(%esp)
c0108dfc:	8b 45 08             	mov    0x8(%ebp),%eax
c0108dff:	ff d0                	call   *%eax
            break;
c0108e01:	eb 27                	jmp    c0108e2a <vprintfmt+0x3d1>

        // unrecognized escape sequence - just print it literally
        default:
            putch('%', putdat);
c0108e03:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108e06:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108e0a:	c7 04 24 25 00 00 00 	movl   $0x25,(%esp)
c0108e11:	8b 45 08             	mov    0x8(%ebp),%eax
c0108e14:	ff d0                	call   *%eax
            for (fmt --; fmt[-1] != '%'; fmt --)
c0108e16:	ff 4d 10             	decl   0x10(%ebp)
c0108e19:	eb 03                	jmp    c0108e1e <vprintfmt+0x3c5>
c0108e1b:	ff 4d 10             	decl   0x10(%ebp)
c0108e1e:	8b 45 10             	mov    0x10(%ebp),%eax
c0108e21:	48                   	dec    %eax
c0108e22:	0f b6 00             	movzbl (%eax),%eax
c0108e25:	3c 25                	cmp    $0x25,%al
c0108e27:	75 f2                	jne    c0108e1b <vprintfmt+0x3c2>
                /* do nothing */;
            break;
c0108e29:	90                   	nop
    while (1) {
c0108e2a:	e9 36 fc ff ff       	jmp    c0108a65 <vprintfmt+0xc>
                return;
c0108e2f:	90                   	nop
        }
    }
}
c0108e30:	83 c4 40             	add    $0x40,%esp
c0108e33:	5b                   	pop    %ebx
c0108e34:	5e                   	pop    %esi
c0108e35:	5d                   	pop    %ebp
c0108e36:	c3                   	ret    

c0108e37 <sprintputch>:
 * sprintputch - 'print' a single character in a buffer
 * @ch:         the character will be printed
 * @b:          the buffer to place the character @ch
 * */
static void
sprintputch(int ch, struct sprintbuf *b) {
c0108e37:	f3 0f 1e fb          	endbr32 
c0108e3b:	55                   	push   %ebp
c0108e3c:	89 e5                	mov    %esp,%ebp
    b->cnt ++;
c0108e3e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108e41:	8b 40 08             	mov    0x8(%eax),%eax
c0108e44:	8d 50 01             	lea    0x1(%eax),%edx
c0108e47:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108e4a:	89 50 08             	mov    %edx,0x8(%eax)
    if (b->buf < b->ebuf) {
c0108e4d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108e50:	8b 10                	mov    (%eax),%edx
c0108e52:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108e55:	8b 40 04             	mov    0x4(%eax),%eax
c0108e58:	39 c2                	cmp    %eax,%edx
c0108e5a:	73 12                	jae    c0108e6e <sprintputch+0x37>
        *b->buf ++ = ch;
c0108e5c:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108e5f:	8b 00                	mov    (%eax),%eax
c0108e61:	8d 48 01             	lea    0x1(%eax),%ecx
c0108e64:	8b 55 0c             	mov    0xc(%ebp),%edx
c0108e67:	89 0a                	mov    %ecx,(%edx)
c0108e69:	8b 55 08             	mov    0x8(%ebp),%edx
c0108e6c:	88 10                	mov    %dl,(%eax)
    }
}
c0108e6e:	90                   	nop
c0108e6f:	5d                   	pop    %ebp
c0108e70:	c3                   	ret    

c0108e71 <snprintf>:
 * @str:        the buffer to place the result into
 * @size:       the size of buffer, including the trailing null space
 * @fmt:        the format string to use
 * */
int
snprintf(char *str, size_t size, const char *fmt, ...) {
c0108e71:	f3 0f 1e fb          	endbr32 
c0108e75:	55                   	push   %ebp
c0108e76:	89 e5                	mov    %esp,%ebp
c0108e78:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    int cnt;
    va_start(ap, fmt);
c0108e7b:	8d 45 14             	lea    0x14(%ebp),%eax
c0108e7e:	89 45 f0             	mov    %eax,-0x10(%ebp)
    cnt = vsnprintf(str, size, fmt, ap);
c0108e81:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108e84:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0108e88:	8b 45 10             	mov    0x10(%ebp),%eax
c0108e8b:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108e8f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108e92:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108e96:	8b 45 08             	mov    0x8(%ebp),%eax
c0108e99:	89 04 24             	mov    %eax,(%esp)
c0108e9c:	e8 08 00 00 00       	call   c0108ea9 <vsnprintf>
c0108ea1:	89 45 f4             	mov    %eax,-0xc(%ebp)
    va_end(ap);
    return cnt;
c0108ea4:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0108ea7:	c9                   	leave  
c0108ea8:	c3                   	ret    

c0108ea9 <vsnprintf>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want snprintf() instead.
 * */
int
vsnprintf(char *str, size_t size, const char *fmt, va_list ap) {
c0108ea9:	f3 0f 1e fb          	endbr32 
c0108ead:	55                   	push   %ebp
c0108eae:	89 e5                	mov    %esp,%ebp
c0108eb0:	83 ec 28             	sub    $0x28,%esp
    struct sprintbuf b = {str, str + size - 1, 0};
c0108eb3:	8b 45 08             	mov    0x8(%ebp),%eax
c0108eb6:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0108eb9:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108ebc:	8d 50 ff             	lea    -0x1(%eax),%edx
c0108ebf:	8b 45 08             	mov    0x8(%ebp),%eax
c0108ec2:	01 d0                	add    %edx,%eax
c0108ec4:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108ec7:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    if (str == NULL || b.buf > b.ebuf) {
c0108ece:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0108ed2:	74 0a                	je     c0108ede <vsnprintf+0x35>
c0108ed4:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0108ed7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108eda:	39 c2                	cmp    %eax,%edx
c0108edc:	76 07                	jbe    c0108ee5 <vsnprintf+0x3c>
        return -E_INVAL;
c0108ede:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
c0108ee3:	eb 2a                	jmp    c0108f0f <vsnprintf+0x66>
    }
    // print the string to the buffer
    vprintfmt((void*)sprintputch, &b, fmt, ap);
c0108ee5:	8b 45 14             	mov    0x14(%ebp),%eax
c0108ee8:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0108eec:	8b 45 10             	mov    0x10(%ebp),%eax
c0108eef:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108ef3:	8d 45 ec             	lea    -0x14(%ebp),%eax
c0108ef6:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108efa:	c7 04 24 37 8e 10 c0 	movl   $0xc0108e37,(%esp)
c0108f01:	e8 53 fb ff ff       	call   c0108a59 <vprintfmt>
    // null terminate the buffer
    *b.buf = '\0';
c0108f06:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108f09:	c6 00 00             	movb   $0x0,(%eax)
    return b.cnt;
c0108f0c:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0108f0f:	c9                   	leave  
c0108f10:	c3                   	ret    

c0108f11 <rand>:
 * rand - returns a pseudo-random integer
 *
 * The rand() function return a value in the range [0, RAND_MAX].
 * */
int
rand(void) {
c0108f11:	f3 0f 1e fb          	endbr32 
c0108f15:	55                   	push   %ebp
c0108f16:	89 e5                	mov    %esp,%ebp
c0108f18:	57                   	push   %edi
c0108f19:	56                   	push   %esi
c0108f1a:	53                   	push   %ebx
c0108f1b:	83 ec 24             	sub    $0x24,%esp
    next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1);
c0108f1e:	a1 60 3a 12 c0       	mov    0xc0123a60,%eax
c0108f23:	8b 15 64 3a 12 c0    	mov    0xc0123a64,%edx
c0108f29:	69 fa 6d e6 ec de    	imul   $0xdeece66d,%edx,%edi
c0108f2f:	6b f0 05             	imul   $0x5,%eax,%esi
c0108f32:	01 fe                	add    %edi,%esi
c0108f34:	bf 6d e6 ec de       	mov    $0xdeece66d,%edi
c0108f39:	f7 e7                	mul    %edi
c0108f3b:	01 d6                	add    %edx,%esi
c0108f3d:	89 f2                	mov    %esi,%edx
c0108f3f:	83 c0 0b             	add    $0xb,%eax
c0108f42:	83 d2 00             	adc    $0x0,%edx
c0108f45:	89 c7                	mov    %eax,%edi
c0108f47:	83 e7 ff             	and    $0xffffffff,%edi
c0108f4a:	89 f9                	mov    %edi,%ecx
c0108f4c:	0f b7 da             	movzwl %dx,%ebx
c0108f4f:	89 0d 60 3a 12 c0    	mov    %ecx,0xc0123a60
c0108f55:	89 1d 64 3a 12 c0    	mov    %ebx,0xc0123a64
    unsigned long long result = (next >> 12);
c0108f5b:	a1 60 3a 12 c0       	mov    0xc0123a60,%eax
c0108f60:	8b 15 64 3a 12 c0    	mov    0xc0123a64,%edx
c0108f66:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c0108f6a:	c1 ea 0c             	shr    $0xc,%edx
c0108f6d:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0108f70:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    return (int)do_div(result, RAND_MAX + 1);
c0108f73:	c7 45 dc 00 00 00 80 	movl   $0x80000000,-0x24(%ebp)
c0108f7a:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108f7d:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0108f80:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0108f83:	89 55 e8             	mov    %edx,-0x18(%ebp)
c0108f86:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108f89:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0108f8c:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0108f90:	74 1c                	je     c0108fae <rand+0x9d>
c0108f92:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108f95:	ba 00 00 00 00       	mov    $0x0,%edx
c0108f9a:	f7 75 dc             	divl   -0x24(%ebp)
c0108f9d:	89 55 ec             	mov    %edx,-0x14(%ebp)
c0108fa0:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108fa3:	ba 00 00 00 00       	mov    $0x0,%edx
c0108fa8:	f7 75 dc             	divl   -0x24(%ebp)
c0108fab:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0108fae:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0108fb1:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0108fb4:	f7 75 dc             	divl   -0x24(%ebp)
c0108fb7:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0108fba:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0108fbd:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0108fc0:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0108fc3:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0108fc6:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c0108fc9:	8b 45 d4             	mov    -0x2c(%ebp),%eax
}
c0108fcc:	83 c4 24             	add    $0x24,%esp
c0108fcf:	5b                   	pop    %ebx
c0108fd0:	5e                   	pop    %esi
c0108fd1:	5f                   	pop    %edi
c0108fd2:	5d                   	pop    %ebp
c0108fd3:	c3                   	ret    

c0108fd4 <srand>:
/* *
 * srand - seed the random number generator with the given number
 * @seed:   the required seed number
 * */
void
srand(unsigned int seed) {
c0108fd4:	f3 0f 1e fb          	endbr32 
c0108fd8:	55                   	push   %ebp
c0108fd9:	89 e5                	mov    %esp,%ebp
    next = seed;
c0108fdb:	8b 45 08             	mov    0x8(%ebp),%eax
c0108fde:	ba 00 00 00 00       	mov    $0x0,%edx
c0108fe3:	a3 60 3a 12 c0       	mov    %eax,0xc0123a60
c0108fe8:	89 15 64 3a 12 c0    	mov    %edx,0xc0123a64
}
c0108fee:	90                   	nop
c0108fef:	5d                   	pop    %ebp
c0108ff0:	c3                   	ret    
